اتساق البيانات والنسخ

التوافق الموزَّع: مقدمة في Raft و Paxos

18 دقيقة الدرس 7 من 10

التوافق الموزَّع: مقدمة في Raft و Paxos

كثيراً ما تحتاج الأنظمة الموزَّعة إلى اتخاذ قرار جماعي واحد — أيّ عقدة هي القائد الحالي؟، أو ما المدخل التالي في السجل؟، أو هل ينبغي تأكيد هذه المعاملة؟ — حتى حين تكون بعض المشاركين غير متاحة أو بطيئة. تُعرَّف مشكلة التوافق بأنها تحدّي إجماع مجموعة من العقد على قيمة واحدة رغم الأعطال.

التوافق هو المحرّك الكامن خلف كل ضمان تناسق قوي تعلّمته حتى الآن: انتخاب القادة في Kafka، وسجل الإيداعات في etcd، وإدارة الإعدادات في Zookeeper، وقائد الكتابة الوحيد في CockroachDB — كلّها تعتمد على خوارزمية توافق.

لماذا التوافق صعب؟

الاتفاق في غرفة مجتمعين أمر يسير، أما الاتفاق عبر شبكة فلا، لأن:

  • الرسائل قد تتأخر أو تُعيَّر — لا تستطيع عقدة ما التمييز بين زميل بطيء وآخر معطوب.
  • العقد قد تنهار في منتصف العملية — قائد يفشل بعد إرسال اقتراح إلى بعض المتابعين فقط يترك الكتلة في حالة غامضة.
  • لا يوجد ساعة مشتركة — لا يمكن الاعتماد على وقت الجدار لكسر التعادلات بثقة.

تُثبت نتيجة استحالة FLP (فيشر ولينش وباترسون، 1985) أنه لا توجد خوارزمية حتمية يمكنها ضمان التوافق في شبكة غير متزامنة إذا تعطّلت ولو عقدة واحدة. تتحايل الأنظمة الحقيقية على ذلك باستخدام العشوائية أو افتراضات التزامن الجزئي — تقبل بأن التقدّم قد يتوقف لحظياً، لكنها تضمن التقارب كلما استقرّت الشبكة.

فكرة محورية: تضمن خوارزمية التوافق السلامة (لا تتعارض العقد أبداً) في جميع الأوقات، والحيوية (تتقدم الكتلة في نهاية المطاف) كلما استقرّت الشبكة. تختار هذه الخوارزميات التناسق على حساب الإتاحة عند وقوع الأقسام — أي تختار CP في مثلث CAP.

Paxos — الخوارزمية الكلاسيكية

Paxos (ليزلي لامبورت، 1989/1998) هي أول خوارزمية توافق عملية. تعمل في مرحلتين:

  1. مرحلة التحضير (Prepare) — يُرسل المقترِح رسالة Prepare(n) برقم اقتراع n إلى أغلبية المقبِلين. يعد كل مقبِل بعدم قبول أي اقتراح برقم أقل من n، ويُعيد أعلى اقتراح قبِله سابقاً إن وجد.
  2. مرحلة القبول (Accept) — إذا جمع المقترِح وعوداً من أغلبية، أرسل Accept(n, v) حيث v إما قيمته الخاصة أو أعلى قيمة مقبولة مسبقاً تلقّاها. يقبل المقبِلون الاقتراح ما لم يكونوا قد وعدوا باقتراع أعلى. بمجرد قبول الأغلبية تُعدّ القيمة مختارة.

Paxos صحيحة رياضياً لكنها صعبة التنفيذ عملياً. تضمّ متغيّرات كـMulti-Paxos وFast Paxos وFlexible Paxos، كل منها يزيد من تعقيد التنفيذ. من التطبيقات الحقيقية: خدمة القفل Chubby من Google، وApache Zookeeper (بروتوكول ZAB، وهو متغيّر من Paxos).

تحذير: Paxos كما وردت في الورقة الأصلية هي خوارزمية قرار واحد (قيمة واحدة). تحويلها إلى سجل متكرر (Multi-Paxos) يستلزم قرارات هندسية كثيرة أهملتها الورقة — كمعالجة الفجوات، وإيجار القائد، والتغييرات في العضوية — وهي مصدر رئيسي للأخطاء في التنفيذات الإنتاجية.

Raft — التوافق المفهوم

صُمِّم Raft (أونغارو وأوستيرهاوت، 2014) ليكون أسهل في الفهم من Paxos مع تقديم ضمانات مكافئة. يُحلّل المشكلة إلى ثلاثة مشاكل فرعية مستقلة:

  • انتخاب القائد — يوجد قائد واحد بالضبط لكل فترة.
  • نسخ السجل — يستقبل القائد طلبات العملاء، يُلحقها بسجله، ثم يُرسلها للمتابعين.
  • الأمان — إذا أُيِّد إدخال في سجل عقدة ما، سيظهر في سجلات جميع القادة المستقبلين.

الفترات والانتخابات

يقسم Raft الوقت إلى فترات مرقّمة. تبدأ كل فترة بانتخاب. إذا لم يسمع متابع من القائد خلال مهلة انتخاب عشوائية (عادةً 150–300 مللي ثانية)، يصبح مرشّحاً، يزيد رقم الفترة، يُصوّت لنفسه، ويطلب أصوات الأقران. يصبح المرشح قائداً إذا جمع أغلبية الأصوات في فترته. لكون المهلة عشوائية، لا يبدأ سوى مرشح واحد غالباً في الوقت ذاته، تجنّباً للتعادل المتكرر.

نسخ السجل

بعد انتخابه، يُسلسل القائد جميع عمليات الكتابة. يُلحق القائد الكتابة بسجله ثم يُرسلها للمتابعين عبر RPC من نوع AppendEntries. حين تُقرّ الأغلبية الإدخال، يصبح مؤيَّداً، يُطبَّق على آلة الحالة، ويُردّ على العميل. يُطبّق المتابعون الإدخالات المؤيَّدة بالترتيب، مما يُبقي حالتهم مطابقة لحالة القائد.

Raft leader election and log replication flow Node A Node B Node C Timeout Candidate T=1 RequestVote(T=1) RequestVote(T=1) VoteGranted VoteGranted LEADER Term = 1 AppendEntries AppendEntries ACK ACK Committed Reply to client Follower B Log appended Follower C Log appended
تسلسل Raft: تنتهي مهلة العقدة A، تفوز بانتخاب الفترة 1، ثم تُوزّع إدخالاً على الأغلبية قبل التأييد.

Raft مقابل Paxos — مقارنة عملية

تتحمّل كلتا الخوارزميتين ما يصل إلى ⌊(N−1)/2⌋ عطلاً في كتلة من N عقدة — كتلة من 3 عقد تتحمّل عطلاً واحداً، وكتلة من 5 عقد تتحمّل عطلين. الفرق الرئيسي في تعقيد التنفيذ ووضوح التشغيل:

Raft vs Paxos comparison Attribute Raft Paxos (Multi-Paxos) Understandability Explicit, well-specified Notoriously complex Leader election Built-in, randomised timeout Not specified — left to impl. Membership changes Joint consensus / single-step No standard approach Real-world usage etcd, Consul, TiKV, CockroachDB Chubby (Google), Zookeeper (ZAB) Fault tolerance (N nodes) ⌊(N-1)/2⌋ failures ⌊(N-1)/2⌋ failures
مقارنة Raft و Paxos جنباً إلى جنب — ضمانات تحمّل أعطال متطابقة، لكن تعقيد تنفيذ مختلف جداً.

أين تلتقي بالتوافق في الإنتاج

نادراً ما تنفّذ خوارزمية توافق بنفسك — بل تستخدم خدمة تنسيق مبنية فوقها:

  • etcd (مخزن حالة Kubernetes) — يستخدم Raft. يُوصى بكتلة من 3 أو 5 عقد.
  • Apache Zookeeper — يستخدم ZAB (متغيّر من Paxos). يُستخدم في Kafka لبيانات الوسطاء (يُستبدل بنظام KRaft المبني على Raft).
  • Consul — يستخدم Raft. للاكتشاف الخدمي والأقفال الموزّعة.
  • CockroachDB / TiDB — Raft لكل نطاق/منطقة. SQL جغرافي الموزّع بتناسق قوي.
  • Google Spanner — Paxos لكل شريحة، مقترن بـTrueTime لتناسق خارجي.

الدرس العملي للمهندس: عند الحاجة إلى قائد واحد موثوق أو سجل موزّع متناسق، استخدم etcd أو Zookeeper بدلاً من كتابة خوارزميتك الخاصة. أخطاء التوافق خفيّة بشكل مدهش وتستلزم سنوات من الاختبار الإنتاجي لتستقرّ.

نصيحة في الحجم: شغّل دائماً كتلة التوافق بعدد فردي من العقد (3 أو 5 عملياً). لا تكسب كتلة من 4 عقد مقاومة أعطال إضافية على كتلة من 3 عقد — كلتاهما تحتاج 3 عقد لتشكيل الأغلبية — لكن كتلة الأربع أكثر تكلفةً ومعرّضة لـالانقسام (2 مقابل 2) الذي لا يمكن أن تعانيه كتلة ذات عدد فردي.

خصائص الأداء

يُضيف التوافق زمن استجابة لأن كل عملية كتابة يجب أن تستكمل جولة واحدة على الأقل إلى أغلبية العقد قبل التأكيد. في كتلة من 3 عقد داخل مركز بيانات واحد يكون هذا عادةً 1–5 مللي ثانية. عبر مراكز بيانات أو مناطق توفر مختلفة (مثلاً 50 مللي ثانية RTT بين المناطق) تستغرق الكتابة المؤيَّدة على الأقل 50–100 مللي ثانية. لهذا تظل كتل Raft/Paxos في منطقة واحدة، بينما يستخدم التوزيع الجغرافي استراتيجيات نسخ غير متزامنة فوقها.

إنتاجية الكتابة محدودة بقرص القائد ومعالجه لا بعدد العقد — إضافة متابعين لا تزيد إنتاجية الكتابة. يمكن تقديم القراءات من المتابعين في إعدادات متساهلة، لكن القراءة من القائد (أو باستخدام إيجار القائد) ضرورية للقراءات الخطية.

نموذج ذهني: فكّر في Raft كدفتر ملاحظات موثوق للإلحاق فقط، حيث تتطلب كل كتابة موافقة أغلبية الفريق قبل أن تصبح دائمة. القائد يمسك القلم، ويُنتخب قائد جديد تلقائياً إذا صمت الحالي.