System Design

تسلط بر اجماع: راهنمای عملی برای Raft و Paxos

در دنیای سیستم‌های توزیع‌شده، دستیابی به اجماع، گنجینه مقدس است. چگونه چندین گره می‌توانند بر روی یک وضعیت واحد از داده توافق کنند، زمانی که قطعی شبکه، خرابی گره‌ها و تأخیر در پیام‌ها اجتناب‌ناپذیر است؟ پاسخ در الگوریتم‌های اجماع نهفته است. برای معماران سیستم و مهندسان ارشد، درک این پروتکل‌ها نه تنها یک بحث آکادمیک، بلکه ضروری برای ساخت برنامه‌های مقاوم، مقیاس‌پذیر و دارای تحمل خطا است. امروز، دو مورد از تأثیرگذارترین الگوریتم‌ها را بررسی خواهیم کرد: Paxos و Raft.

چالش اجماع در سیستم‌های توزیع‌شده

قبل از ورود به الگوریتم‌های خاص، درک فضای مسئله حیاتی است. در یک سیستم تک‌گره‌ای، نوشتن در پایگاه داده ساده است. با این حال، در یک خوشه توزیع‌شده، شما با ملاحظات قضیه CAP روبرو هستید. برای حفظ سازگاری و در دسترس بودن، به روشی نیاز داریم که تضمین کند تمام کپی‌ها بر روی ترتیب عملیات توافق دارند. اینجا جایی است که اجماع وارد می‌شود. هدف ساده است: با فرض مجموعه‌ای از ورودی‌ها، تمام گره‌های سالم باید در نهایت بر روی یک خروجی یکسان تصمیم بگیرند.

Paxos: پایه نظری

Paxos که توسط لسلی لامپورت پیشنهاد شد، الگوریتم بنیادی برای اجماع توزیع‌شده است. این الگوریتم به طور مشهوری پیچیده است و اغلب به عنوان «الگوریتمی که هیچ‌کس آن را درک نمی‌کند» توصیف می‌شود. با وجود پیچیدگی، این الگوریتم تضمین‌های قوی را تحت همگرایی جزئی و خرابی‌های کرش (Crash) ارائه می‌دهد.

Paxos در دو فاز عمل می‌کند: فاز آماده‌سازی (Prepare) و فاز پذیرش (Accept). در فاز آماده‌سازی، یک پیشنهاددهنده (رهبر کاندیدا) از گره‌ها می‌خواهد که قول بدهند پیشنهادها با اولویت پایین‌تر را نپذیرند. در فاز پذیرش، اگر اکثریت توافق کنند، پیشنهاددهنده یک مقدار را پیشنهاد می‌دهد. اگر اکثریت آن را بپذیرند، مقدار انتخاب می‌شود.

با وجود قدرت بالا، پیاده‌سازی صحیح Paxos به دلیل مدیریت ظریف شناسه‌های پیشنهاددهنده و انتخاب مقدار دشوار است. در زیر نمایش شبه‌کد منطق اصلی آمده است:

// فاز انتخاب رهبر
on START_ELECTION(node_id):
    ballot_id = generate_unique_ballot()
    wait_for_majority(reply):
        if reply.promises_to(node_id, ballot_id):
            move_to_proposal_phase(ballot_id)

// فاز پیشنهاد
on move_to_proposal_phase(ballot_id):
    value = select_value() // معمولاً آخرین نوشته شده یا جدید
    broadcast_proposal(ballot_id, value)
    wait_for_majority(acceptance):
        if accepted:
            leader_status = ACTIVE
            persist_value(value)

Raft: اجماع برای انسان‌ها

با توجه به مشکلات پیاده‌سازی Paxos، دیگو اونگارو و جان اوسترهوت در سال ۲۰۱۴ Raft را طراحی کردند. Raft برای درک‌پذیری طراحی شده است. این الگوریتم اجماع را به سه زیرمسئله تجزیه می‌کند: انتخاب رهبر، بازتولید لاگ و ایمنی. با معرفی یک مدل رهبر قوی، Raft ماشین حالت مورد نیاز برای هر گره را ساده می‌کند.

در Raft، گره‌ها در یکی از سه حالت وجود دارند: پیرو (Follower)، کاندیدا (Candidate) یا رهبر (Leader). زمان به دوره‌های (Terms) تقسیم می‌شود. انتخابات زمانی رخ می‌دهند که یک پیرو خرابی رهبر را مشکوک بداند (تایم‌اوت انتخابات). کاندیدا درخواست رأی می‌دهد؛ اگر اکثریت را دریافت کند، رهبر می‌شود و شروع به افزودن ورودی‌های لاگ می‌کند.

// انتقال‌های ماشین حالت در Raft
function on_message(node, msg):
    if msg.type == HEARTBEAT:
        update_last_seen(msg.leader_id)
        reset_election_timeout()
    
    if msg.type == REQUEST_VOTE:
        if msg.term >= current_term:
            current_term = msg.term
            vote_for = msg.candidate_id
            send(VOTE_GRANTED, msg.candidate_id)
            
    if msg.type == APPEND_ENTRIES:
        if msg.term >= current_term:
            append_log(msg.entries)
            send(APPEND_RESPONSE, success=true)

Raft در برابر Paxos: چه زمانی کدام را انتخاب کنیم؟

اگرچه هر دو الگوریتم یک مشکل بنیادی یکسان را حل می‌کنند، کاربردهای عملی آن‌ها متفاوت است. Paxos اغلب در سیستم‌هایی استفاده می‌شود که در آن‌ها استحکام نظری اولویت اصلی دارد و پیچیدگی پیاده‌سازی می‌تواند از طریق کتابخانه‌ها (مانند Chubby گوگل یا ZooKeeper که از یک نسخه تغییر یافته Paxos استفاده می‌کند) انتزاع شود. با این حال، Raft برای سیستم‌های جدیدی مانند etcd و Consul ترجیح داده می‌شود زیرا پیاده‌سازی، اشکال‌زدایی و گسترش آن آسان‌تر است. مدل رهبر صریح آن، عملیاتی مانند فشرده‌سازی لاگ و تغییرات عضویت را شهودی‌تر می‌کند.

نتیجه‌گیری

الگوریتم‌های اجماع، ستون فقرات زیرساخت توزیع‌شده مدرن هستند. چه در حال طراحی یک پایگاه داده، صف پیام یا یک سرویس پیکربندی باشید، درک ملاحظات بین Paxos و Raft حیاتی است. Raft رویکردی عمل‌گرایانه‌تر برای بیشتر چالش‌های مهندسی معاصر ارائه می‌دهد و وضوح را بدون قربانی کردن قابلیت اطمینان فراهم می‌کند. هنگامی که سیستم توزیع‌شده بعدی خود را طراحی می‌کنید، به یاد داشته باشید که اجماع فقط درباره توافق بر روی داده نیست؛ بلکه درباره ساخت اعتماد در محیطی نامطمئن است.

Share: