این کتاب (Latency: Reduce Delay in Software Systems) یکی از بهترین منابع برای درک Trade-offهای سیستمهای توزیعشده است. یکی از مهمترین فصلهای آن درباره Consistency Models است. خیلیها فکر میکنند Consistency فقط یعنی "داده یکی باشد"، در حالی که موضوع اصلی این است:
بعد از اینکه یک Write انجام شد، چه زمانی همهی Replicaها همان مقدار را خواهند دید؟
در سیستمهای Distributed همیشه بین Latency، Availability و Consistency باید انتخاب انجام دهی.
قبل از هر چیز یه تصویر ذهنی کلی داشته باش: وقتی داده رو روی چند تا سرور/رپلیکا (replica) کپی میکنی (که برای کاهش latency و بالا بردن availability لازمه)، یه سوال اساسی پیش میاد: وقتی یه نفر داده رو آپدیت میکنه، بقیهی کسایی که دارن از رپلیکاهای دیگه میخونن، کِی و چقدر مطمئن اون آپدیت رو میبینن؟ جواب این سوال، همون consistency model هست. هرچی consistency قویتر باشه، معمولاً latency بیشتر میشه — دقیقاً همون trade-off که تو کتاب Latency روش تمرکز شده.
۱. Strong Consistency (سازگاری قوی)
سادهترین تعریف: انگار فقط یک کپی از داده وجود داره، حتی اگه واقعاً چند تا رپلیکا داری.
- هر write که تموم بشه، از اون لحظه به بعد هر read از هر جا (هر رپلیکا) همون مقدار جدید رو برمیگردونه.
- هیچکس هیچوقت دادهی "قدیمی" یا stale نمیبینه.
- برای این تضمین، سیستم باید رپلیکاها رو با هم هماهنگ کنه (مثلاً از طریق consensus/الگوریتمهایی مثل Paxos یا Raft)، و همین هماهنگی latency رو بالا میبره چون باید صبر کنی تا همه (یا اکثریت) تایید کنن.
- مثال ذهنی: مثل یه دفترچهی حساب بانکی که فقط یه نسخهازش وجود داره؛ هر کی نگاش کنه، آخرین موجودی رو میبینه.
- کجا لازمه: تراکنشهای بانکی، موجودی انبار، جاهایی که خطای کوچیک هم فاجعهست.
۲. Eventual Consistency (سازگاری نهایی)
اینجا دیگه هیچ تضمین فوری نداری.
- بعد از write، اگه بلافاصله بری از یه رپلیکای دیگه بخونی، ممکنه هنوز دادهی قدیمی رو ببینی.
- تنها قولی که سیستم میده اینه: اگه دیگه write جدیدی اتفاق نیفته، بالاخره (eventually) همهی رپلیکاها به یه مقدار یکسان میرسن.
- هیچ محدودیتی روی "چقدر طول میکشه" یا "چقدر قدیمی میتونه باشه" وجود نداره — فقط میگه بالاخره درست میشه.
- در عوض، خیلی سریع و در دسترسه (latency پایین، availability بالا) چون هر رپلیکا فوراً جواب میده بدون اینکه منتظر بقیه بمونه.
- مثال: مثل DNS یا سیستمهایی مثل Amazon Dynamo. اگه یه ریویو تو آمازون بذاری، ممکنه چند ثانیه طول بکشه تا همه جا نمایش داده بشه، ولی خب مهم نیست چون اتفاق فاجعهباری نمیافته.
۳. Causal Consistency (سازگاری علّی)
این یکی بین strong و eventual یه جای میونه قرار میگیره — هوشمندانهتر از eventual ولی سبکتر از strong.
- فقط عملیاتهایی که با هم رابطهی علّی (cause-and-effect) دارن باید به ترتیب دیده بشن؛ عملیاتهای بیربط به هم (concurrent) میتونن به ترتیبهای متفاوت دیده بشن.
- مثال کلاسیک: تصور کن تو یه پست کامنت میذاری "این عکس محشره!" و بعد یکی دیگه زیرش ریپلای میده "موافقم!". این دو تا causally related هستن (ریپلای، وابسته به کامنت اوله). causal consistency تضمین میده که هیچوقت کسی اول ریپلای رو ببینه بدون اینکه کامنت اصلی رو دیده باشه — چون این بیمعنی میشه.
- ولی اگه دو نفر جدا از هم، بدون اطلاع از هم، دو تا کامنت مستقل بذارن، میتونن به ترتیبهای متفاوتی برای کاربرای مختلف نمایش داده بشن، مشکلی نیست چون بینشون رابطهی علّی نیست.
- خلاصه: نظم رو فقط اونجایی حفظ میکنه که "معنا" داره، و همینه که باعث میشه هم سریعتر از strong باشه هم منطقیتر از eventual.
۴. Session Consistency (سازگاری نشست)
این یکی یه نسخهی عملی و محدودتر از causal consistency هست، ولی محدودهش رو به یه session (یعنی یه کاربر خاص، تو یه بازهی زمانی خاص) میبنده.
- تضمینهاش فقط برای همون کاربر، در همون session برقراره؛ دربارهی بقیهی کاربرا هیچ قولی نمیده.
- معمولاً شامل چند تا زیرتضمینه، مثلاً:
- Read-your-writes: اگه خودت چیزی رو آپدیت کردی، خودت همیشه نسخهی جدیدشو میبینی (نه قدیمی رو).
- Monotonic reads: اگه یه بار یه مقدار جدید رو دیدی، دیگه تو همون session نباید برگردی به یه مقدار قدیمیتر.
- Monotonic writes: نوشتههای خودت به همون ترتیبی که انجامشون دادی، ثبت و دیده میشن.
- مثال: خودت یه پست تو شبکهی اجتماعی ادیت میکنی و رفرش میکنی — همیشه باید نسخهی خودت رو ببینی، حتی اگه یه کاربر دیگه که رفته رو یه رپلیکای دیگه هنوز نسخهی قدیمی رو ببینه.
- این مدل همون latency و availability شبیه eventual consistency رو داره، ولی برای خودِ کاربر تجربهی بهمراتب منطقیتری میسازه — چون اصلاً هیچکس دوست نداره پستی که خودش الان ادیت کرده رو رفرش کنه و نسخهی قدیمی ببینه!
جمعبندی خیلی خلاصه برای نوتبرداری:
| مدل | تضمین | Latency |
|---|---|---|
| Strong | همه همیشه آخرین مقدار رو میبینن | بالا |
| Eventual | بالاخره یه روز همه یکی میشن، بدون تضمین زمان | پایین |
| Causal | فقط عملیاتهای بههممرتبط، ترتیب حفظ میشه | متوسط |
| Session | تضمین فقط برای خود کاربر تو همون session | پایین (ولی تجربهی کاربری خوب) |
ارتباط این مدلها با CAP Theorem
تقریباً همهی این مدلها نتیجهی تصمیمی هستند که در CAP گرفته میشود:
- Strong Consistency معمولاً به سمت Consistency (C) متمایل است و در زمان Partition ممکن است Availability را قربانی کند.
- Eventual Consistency بیشتر روی Availability (A) تمرکز میکند و Consistency را به زمان آینده موکول میکند.
- Causal و Session Consistency راهحلهای میانی هستند. آنها تلاش میکنند بدون هزینهی کامل Strong Consistency، تجربهی منطقیتری برای کاربر ایجاد کنند.
به همین دلیل در سیستمهای مدرن کمتر میبینی که کل سیستم فقط یک مدل Consistency داشته باشد. معمولاً هر بخش، مدل مناسب خودش را انتخاب میکند.
برای مثال در یک فروشگاه اینترنتی:
- پرداخت و موجودی کالا از Strong Consistency استفاده میکنند.
- تعداد لایک و بازدید محصول Eventual Consistency است.
- نمایش پیامهای گفتگو میتواند Causal Consistency داشته باشد.
- پروفایل و تنظیمات کاربر معمولاً با Session Consistency پیادهسازی میشوند.
نکتهای که کتاب Latency بارها روی آن تأکید میکند این است که Consistency رایگان نیست. هرچه تضمین قویتری بخواهی، معمولاً باید هزینهی بیشتری از نظر Latency، هماهنگی بین Replicaها و کاهش Availability بپردازی. بنابراین سؤال درست در طراحی سیستم این نیست که «کدام مدل بهتر است؟» بلکه این است:
برای این قابلیت، حداقل سطح Consistency موردنیاز چیست که نیاز کسبوکار را برآورده کند و در عین حال کمترین Latency ممکن را داشته باشد؟
این دقیقاً طرز فکر یک System Designer است، نه صرفاً یک برنامهنویس.