System Design শেখো
শেখো / ডিস্ট্রিবিউটেড সিস্টেম থিওরি

2PC vs 3PC

11 মিনিট Module 6 · Distributed Systems Theory
এক নজরে
  • Distributed transaction-এ একাধিক নোডকে হয় সবাই commit করতে হবে নয়তো সবাই abort করতে হবে — এটাই atomic commit-এর সমস্যা।
  • 2PC দুই ধাপে (prepare ও commit) এটা সমাধান করে, কিন্তু coordinator মরে গেলে participant-রা আটকে যায় (blocking)।
  • 3PC একটা বাড়তি ধাপ দিয়ে blocking কমায়, তবু জটিল ও partition-অসহিষ্ণু; বাস্তবে অনেকে Saga বেছে নেয়।

সমস্যাটা কী?

ধরো একটা e-commerce অর্ডার সম্পন্ন করতে তিনটা আলাদা সার্ভিসে কাজ করতে হবে — Inventory থেকে পণ্য কমানো, Payment থেকে টাকা কাটা, আর Shipping-এ ডেলিভারি বুক করা। এখন সমস্যা: এই তিনটার মধ্যে হয় সবগুলো সফল হতে হবে, নয়তো একটাও না। টাকা কাটলো অথচ পণ্য বুক হলো না — এমন আধাখেঁচড়া অবস্থা ভয়াবহ।

একটামাত্র database-এ এটা সহজ — local transaction-এর ACID গুণ এটা নিশ্চিত করে। কিন্তু তিনটা আলাদা মেশিন/সার্ভিসে? কেউ একজন "হ্যাঁ" বললো, কেউ "না", কেউ মাঝপথে ক্র্যাশ করলো — এই বিশৃঙ্খলায় সবাইকে একমত করানোর সমস্যাই distributed atomic commit

মূল ধারণা

Atomic commit: একাধিক নোড জড়িত একটি transaction-এর জন্য এমন একটি protocol, যা নিশ্চিত করে হয় সব নোড একসাথে commit করবে, নয়তো সব নোড একসাথে abort করবে — কখনো মিশ্র অবস্থা হবে না।

এই সমন্বয়ের কাজটা সাধারণত একজন coordinator (লেনদেন ব্যবস্থাপক) করে। বাকিরা participant বা cohort। coordinator সবাইকে জিজ্ঞেস করে, ভোট নেয়, তারপর একটা চূড়ান্ত সিদ্ধান্ত সবাইকে জানিয়ে দেয়। মূল চ্যালেঞ্জ হলো — এই প্রক্রিয়ার যেকোনো মুহূর্তে যেকোনো নোড বা network মরে যেতে পারে, তবু সিদ্ধান্ত যেন সামঞ্জস্যপূর্ণ থাকে।

কীভাবে কাজ করে

Two-Phase Commit (2PC)

Phase 1 — Prepare (voting): coordinator সবাইকে জিজ্ঞেস করে "commit করতে পারবে?" প্রতিটা participant কাজটুকু করে রাখে, লক ধরে রাখে, log-এ লেখে, তারপর "Yes" বা "No" ভোট দেয়। একবার "Yes" বললে সে আর পিছাতে পারে না — সে এখন prepared অবস্থায়।

Phase 2 — Commit/Abort: সবাই "Yes" বললে coordinator "Commit" পাঠায়; কেউ "No" বললে "Abort"। participant-রা সেই অনুযায়ী কাজ পাকা করে বা বাতিল করে, lock ছাড়ে।

2PC-র মূল দুর্বলতা

সমস্যা হলো participant "Yes" বলার পর যদি coordinator চূড়ান্ত সিদ্ধান্ত পাঠানোর আগেই ক্র্যাশ করে — participant এখন আটকে। সে একা commit-ও করতে পারে না (অন্যরা হয়তো abort করবে), abort-ও করতে পারে না (অন্যরা হয়তো commit করবে)। সে lock ধরে অনির্দিষ্টকাল অপেক্ষায় থাকে। এটাই blocking problem — 2PC-কে fragile বানিয়ে দেয়।

Three-Phase Commit (3PC)

3PC একটা বাড়তি ধাপ যোগ করে blocking কমায়:

  1. CanCommit? — ভোট নেওয়া।
  2. PreCommit — সবাই "Yes" বললে coordinator "তৈরি হও" পাঠায়; এখন সবাই জানে সিদ্ধান্ত commit-এর দিকে।
  3. DoCommit — চূড়ান্ত commit।

মূল কৌশল: যদি coordinator মরেও যায়, participant timeout-এর পর নিরাপদে অনুমান করতে পারে — কেউ যদি PreCommit পেয়ে থাকে, সবাই commit করবে।

তুলনা

বৈশিষ্ট্য2PC3PC
ধাপ সংখ্যা
Blockingহ্যাঁ (coordinator মরলে)অনেক কম
Network round-tripকম, দ্রুতবেশি, ধীর
Network partition সহনশীলনানা (partition-এ ভুল করতে পারে)
বাস্তবে ব্যবহারমোটামুটি (XA)প্রায় নেই

প্রকারভেদ

সহজ উদাহরণ

ভাবো একটা বিয়ের আয়োজন। কাজি (coordinator) আগে বর-কনে দুজনকে আলাদা জিজ্ঞেস করেন "রাজি আছো?" (Prepare)। দুজনই "কবুল" বললে তবেই বিয়ে পাকা ঘোষণা করেন (Commit)। কিন্তু যদি কনে "কবুল" বলার পর কাজি হঠাৎ অজ্ঞান হয়ে যান (coordinator crash) — কনে এখন আটকে, সে জানে না বিয়ে হলো কি না, অন্য কারো সাথে কথাও এগোতে পারে না (blocking)। 3PC-তে কাজি মাঝখানে "প্রায় হয়ে গেছে, প্রস্তুত হও" বলে রাখেন, যাতে তিনি অজ্ঞান হলেও বাকিরা বুঝে এগোতে পারে।

কৌশল

বিকল্প পথ — Saga pattern:

distributed lock আর atomic commit-এর ভার এড়াতে Saga পুরো transaction-কে ভেঙে কতগুলো ছোট local transaction-এ পরিণত করে। প্রতিটা ধাপ নিজে commit হয়। কোনো ধাপ ব্যর্থ হলে আগের ধাপগুলোর জন্য compensating transaction চালিয়ে undo করা হয় — যেমন টাকা কাটা হয়ে থাকলে refund করা।

  • Orchestration Saga: একটা কেন্দ্রীয় orchestrator ধাপগুলো পরিচালনা করে।
  • Choreography Saga: প্রতিটা সার্ভিস event শুনে নিজে পরের কাজ করে, কোনো কেন্দ্রীয় বস নেই।

Saga strong atomicity দেয় না — মাঝপথে অন্যরা inconsistent অবস্থা দেখতে পারে — কিন্তু eventual consistency আর high availability দেয়, যা microservices-এ বেশি বাস্তবসম্মত।

কখন ব্যবহার করবে / করবে না

  • 2PC — যখন সব participant একই trusted datacenter-এ, transaction ছোট ও দ্রুত, এবং তোমার শক্ত atomicity দরকার (যেমন একটি distributed SQL database-এর ভেতরে)।
  • Saga — যখন long-running business workflow, microservices, এবং availability lock-এর চেয়ে বেশি জরুরি।
সাবধান

2PC কখনো high-latency বা অবিশ্বস্ত network-এ (যেমন বিভিন্ন datacenter জুড়ে microservices) ব্যবহার করতে যেও না। coordinator একটা single point of failure, আর blocking-এর সময় participant-রা lock ধরে রাখে — ফলে পুরো সিস্টেমের throughput ধসে পড়তে পারে। 3PC তাত্ত্বিকভাবে ভালো শোনালেও network partition-এ ভুল সিদ্ধান্ত নিতে পারে, তাই বাস্তবে প্রায় কেউ ব্যবহার করে না।

বাস্তব উদাহরণ

  • XA transactions (Java JTA, MySQL XA): চিরায়ত 2PC, এন্টারপ্রাইজ database integration-এ।
  • PostgreSQL: PREPARE TRANSACTION দিয়ে 2PC-র prepare phase সমর্থন করে।
  • Microservices (e-commerce checkout): প্রায় সবাই Saga ব্যবহার করে — order, payment, inventory ধাপে ভাগ করে, ব্যর্থ হলে compensate।
  • Google Spanner: internally Paxos-backed 2PC ব্যবহার করে, কিন্তু coordinator-ও replicated হওয়ায় classic blocking সমস্যা অনেকাংশে এড়ায়।
টিপস

ইন্টারভিউতে "distributed transaction কীভাবে সামলাবে" জিজ্ঞেস করলে শুধু 2PC বলে থেমো না। বলো — 2PC শক্ত atomicity দেয় কিন্তু coordinator crash-এ blocking হয় ও single datacenter-এর বাইরে দুর্বল; তাই microservices-এ আমি Saga + compensating transaction দিয়ে eventual consistency বেছে নেব। এই trade-off awareness ইন্টারভিউয়ারকে মুগ্ধ করে।

মূল শব্দ (Key Terms)

মিনি কুইজ

1. 2PC-তে coordinator যদি commit সিদ্ধান্তের পর কিন্তু সবাইকে জানানোর আগেই ক্র্যাশ করে, participant-দের কী হয়?

2. 3PC কীভাবে blocking কমানোর চেষ্টা করে?

3. Saga pattern কীভাবে 2PC থেকে আলাদা?