دربارهٔ این فصل
یادداشتِ همراه نوارتا حالا به این فکر کردهاید که اگر در یک پایگاه داده توزیعشده، دو نفر همزمان به اطلاعات متفاوتی نگاه کنند، سیستم چطور باید تصمیم بگیرد کدام نسخه درست است؟ وقتی شبکه با تاخیر مواجه میشود یا گرهها از کار میافتند، هماهنگ نگه داشتن تمام بخشهای یک سیستم بزرگ به یکی از پیچیدهترین چالشهای مهندسی نرمافزار تبدیل میشود.
در کتاب «طراحی برنامههای دادهگرا» نوشتهٔ «مارتین کلپمن»، فصل نهم به بررسی دقیق مفهوم سازگاری (consistency) و اجماع (consensus) میپردازد تا نشان دهد چطور میتوانیم سیستمهای توزیعشدهای بسازیم که در برابر خطاها مقاومت کنند. درک این مفاهیم به ما کمک میکند تا حد و مرز تضمینهایی را که پایگاههای داده میتوانند به ما بدهند به خوبی بشناسیم.
یکی از قویترین مدلهای سازگاری، خطیسازیپذیری (linearizability) است؛ ویژگیای که باعث میشود سیستم طوری رفتار کند که انگار فقط یک نسخه از داده وجود دارد و تمام عملیات بهصورت اتمی روی آن انجام میشوند. مشکل اینجاست که تضمین تازگی دادهها در خطیسازیپذیری هزینه دارد و سیستم را در برابر مشکلات شبکه آسیبپذیر میکند. مثلاً اگر وبسایتی نتواند این تضمین را بدهد، ممکن است کاربری امتیاز مسابقه فوتبال را زودتر از کاربر دیگر روی صفحه ببیند که این موضوع تجربه گیجکنندهای ایجاد میکند.
موضوع مهم دیگر، ترتیب رویدادها و علیت (causality) در سیستمهای توزیعشده است. علت همیشه قبل از معلول اتفاق میافتد و حفظ این رابطه برای جلوگیری از تناقضهایی مثل دیدن پاسخ یک سوال قبل از خود سوال حیاتی است. ترتیبسنجی کامل با استفاده از روشهایی مانند تمبرهای لامپورت (Lamport timestamps) که به هر رویداد یک جفت شمارنده و شناسهٔ گره اختصاص میدهند، کمک میکند تا رویدادها بهگونهای مرتب شوند که با روابط علّی سازگار بمانند.
وقتی صحبت از نوشتن دادهها در میان چند گره میشود، سیستمهای پایگاه داده گاهی به توافق جمعی نیاز دارند که به آن مسئلهٔ تعهد اتمی (atomic commit) میگویند. پروتکل تعهد دو مرحلهای (two-phase commit) تلاشی برای حل این مشکل است که در آن هماهنگکننده ابتدا از همه میپرسد که آیا آمادهٔ ذخیره هستند یا نه، و بعد از گرفتن پاسخ مثبت، فرمان نهایی را صادر میکند. با این حال، اگر هماهنگکننده در میان راه سقوط کند، گرهها در حالت نامطمئن معلق میمانند و قفلها آزاد نمیشوند.
برای حل اساسی این چالشها، سیستمهای اجماع (consensus) وارد میدان میشوند تا به گرهها کمک کنند روی یک تصمیم واحد به توافق برسند. ابزارهایی مثل زوکیپر (Apache ZooKeeper) از الگوریتمهای اجماع برای پیادهسازی پخش ترتیب کامل (total order broadcast) استفاده میکنند؛ به این معنا که همهٔ پیامها دقیقاً با یک ترتیب مشخص به تمام گرهها میرسند تا تکرار دادهها بدون تناقض انجام شود.
پیشنهاد من این است که پیش از پیادهسازی معماریهای پیچیدهٔ توزیعشده، بهدقت بررسی کنید که آیا برنامهتان واقعاً به خطیسازیپذیری سختگیرانه نیاز دارد یا سازگاریهای ضعیفتر و سریعتر برای نیازهای محصول شما کفایت میکنند. انتخاب درست مدل سازگاری میتواند معماری نرمافزار شما را از پیچیدگیهای غیرضروری نجات دهد.
امیدوارم این مرور کوتاه به روشنتر شدن ابعاد سازگاری و اجماع در سیستمهای توزیعشده کمک کرده باشد؛ منتظر نظرات شما در بخش گفتگو هستیم.