في عالم هندسة البرمجيات الحديثة، تعد الموثوقية أمراً بالغ الأهمية. مع انتقالنا من التطبيقات أحادية العقدة إلى الأنظمة الموزعة، يصبح ضمان اتفاق جميع العقد على حالة البيانات أمراً حاسماً. هنا تأتي خوارزميات الإجماع لتلعب دورها. فهي حجر الأساس لقواعد البيانات الموزعة، وطوابير الرسائل، والأقفال الموزعة. اليوم، سنستكشف خوارزميتين من أكثر الخوارزميات تأثيراً في هذا المجال: Paxos و Raft.
مشكلة الإجماع
تخيل مجموعة مكونة من ثلاثة خوادم تخزن نفس البيانات. إذا تعطل الخادم A، يجب على الخوادم المتبقية أن تقرر أي قطعة من البيانات هي الصحيحة. تظهر سيناريوهات أكثر تعقيداً عندما تنقسم الشبكة، أو تتأخر الرسائل، أو تقترح عقد متعددة تحديثات مختلفة في وقت واحد. يسمح خوارزمية الإجماع لمجموعة من العقد بالاتفاق على قيمة واحدة، حتى إذا تعطلت بعض العقد أو تصرفت بشكل خبيث.
التحدي الأساسي هو تحقيق الاتساق، والتوفر، وتحمل الانقسام (نظرية CAP) في بيئة غير متزامنة حيث تكون الأعطال حتمية.
Paxos: الأساس النظري
اخترعت ليزي لامبورت خوارزمية Paxos في عام 1989، وهي تُعد على الأرجح أشهر خوارزمية إجماع. صُممت للبقاء في وجه انقسامات الشبكة وأعطال العقد. وعلى الرغم من أناقتها النظرية، إلا أن تنفيذ Paxos وتصحيح الأخطاء فيه معروفان بصعوبتهما الشديدة بسبب تعقيده ومراحله غير البديهية (اقتراح، قبول، تعلم).
تعمل Paxos من خلال انتخاب قائد. القائد هو العقدة الوحيدة المسموح لها باقتراح تغييرات على الحالة. تقبل العقد الأخرى (الأتباع) هذه الاقتراحات إذا لم تكون قد قبلت اقتراحاً ذا رقم أعلى من قبل. يضمن البروتوكول أنه بمجرد اختيار قيمة، لا يمكن التراجع عنها.
على الرغم من أننا نادراً ما نكتب كود Paxos الخام، فإن فهم منطق الإغلاق ثنائي المرحلة الخاص به أمر حيوي لفهم سبب عمل المعاملات الموزعة. فيما يلي تمثيل مفاهيمي مبسط لتدفق الاقتراح:
function propose(node, proposal_id, value):
if node.role == LEADER:
prepare(proposal_id) // Phase 1: Ask followers for promises
// Phase 2: If majority promised, accept the value
accept(proposal_id, value)
else:
handle_proposal(proposal_id, value)
Raft: جعل الإجماع قابلاً للفهم
صُممت Raft خصيصاً لمعالجة صعوبات تنفيذ Paxos. طوّرها دييغو أونغارو وجون أوسترهوت في جامعة ستانفورد، وقسمت Raft الإجماع إلى ثلاث مشكلات فرعية: انتخاب القائد، وتكرار السجل، والسلامة.
تعد Raft أسهل بكثير في الاستدلال عليها لأنها تعتمد على إدارة صريحة للقائد. في Raft، يمكن أن تكون العقد في إحدى ثلاث حالات: القائد، والأتباع، أو المرشح. يضمن النظام وجود قائد واحد فقط في أي وقت معين.
عندما يفشل القائد، يتم تشغيل عملية انتخاب. يبدأ الأتباع مؤقتاتهم؛ أول من ينتهي وقته يصبح مرشحاً ويطلب الأصوات. إذا تلقى المرشح أغلبية الأصوات، يصبح القائد الجديد ويبدأ في إضافة إدخالات إلى سجله، والتي يقوم بعد ذلك بتكرارها إلى الأتباع.
رؤى التنفيذ العملية
بالنسبة للمطورين، على الأرجح لن تقوم بتنفيذ Raft من الصفر ما لم تكن تبني قاعدة بيانات موزعة أساسية. بدلاً من ذلك، ستستخدم مكتبات مثل etcd، وconsul، أو ZooKeeper، التي تنفذ هذه البروتوكولات تحت الغطاء. ومع ذلك، فإن فهم التدفق يساعد في تصحيح الأخطاء مثل سيناريوهات "تقسيم الدماغ" أو ارتفاع زمن الاستجابة أثناء انتخابات القادة.
خذ بعين الاعتبار هذا الزائف للكود لفحص نبضات القلب بأسلوب Raft، والذي يمنع الانتخابات غير الضرورية:
function checkHeartbeat(node):
last_heartbeat_time = get_last_message_time(node)
current_time = now()
if (current_time - last_heartbeat_time) > ELECTION_TIMEOUT:
transition_to_candidate(node)
start_election(node)
else:
stay_as_follower(node)
الخاتمة
يعتمد الاختيار بين Paxos و Raft غالباً على خبرة فريقك والمتطلبات المحددة لنظامك. تظل Paxos المعيار الذهبي للصحة النظرية وتُستخدم في أنظمة مثل Chubby و Bigtable. ومع ذلك، اكتسبت Raft شعبية هائلة في النظم الإيكولوجية الحديثة للسحابة (مثل etcd و TiDB) بسبب وضوحها وسهولة تنفيذها.
مع استمرار تطور الأنظمة الموزعة، فإن إتقان آليات الإجماع هذه ليس مجرد تمرين أكاديمي—إنه ضرورة عملية لبناء برمجيات مرنة وقابلة للتوسع ومتحملة للأعطال. من خلال فهم كيفية اتفاق العقد، تمكّن نفسك من تصميم أنظمة تظل قوية حتى عندما لا تعمل الشبكة بشكل صحيح.