محسن میرزانیا
محسن میرزانیا
خواندن ۶ دقیقه·۵ سال پیش

برنامه‌های "cloud-native" - قسمت چهارم Eventual Consistency

مفهوم “Eventual Consistency” راهکاری برای چالش‌های یکپارچگی داده‌ها (یا “data consistency”) در سیستم‌های توزیع‌شده است. منظور از “eventual consistency” به زبان ساده یعنی اینکه در یک پایگاه‌داده‌ی “eventually consistent”، درخواست‌های همزمان به مقدار یک داده، می‌تواند مقدارهای مختلفی را برگرداند. اما نکته‌ی مهم این است که این وضعیت گذرا است، و مقادیر “در نهایت” یکسان خواهند شد. اما چرا باید از این مدل استفاده شود؟ همان‌طورکه در ادامه توضیح خواهیم داد، استفاده از این مدل باعث scalability بهتر، کارایی بیشتر، و هزینه‌ی کمتر خواهد شد.

در هر زمان، اکثر داده‌های یک پایگاه‌داده‌ی “eventually consistent” در جاهای مختلف یکسان هستند، اما ممکن است تعداد کمی از آن‌ها هم در حال آپدیت شدن باشند. یعنی ممکن است مقادیر یک داده برای چند ثانیه غیر یکسان باشند، اما این موضوع حتمی نیست؛ زیرا بستگی به اپلیکیشن و شرایط حال حاضر دارد.


تئوری CAP و Eventual Consistency

تئوری CAP بیان می‌کند که در یک سیستم توزیع‌شده سه نوع تضمین را می‌توان در ارتباط با اطلاعات تعریف کرد:

  • Consistency
  • Availability
  • Partition Tolerance

یکپارچگی یا Consistency به این معناست که هر کاربری، پاسخ یکسانی را از سیستم دریافت کند. در دسترس پذیری یا Availability به این معناست که کاربران همیشه بتوانند به سیستم دسترسی پیدا کنند (حتا اگر بخشی از سیستم دچار failure شود). Partition tolerance به این معناست که اگر نودهایی از شبکه جدا شوند و نتوانند با دیگر نودها ارتباط برقرار کنند، سیستم به درستی به کار خود ادامه دهد.

تئوری CAP بیان می‌کند که هر اپلیکیشنی از این سه تضمین متفاوت، تنها می‌تواند دو مورد را انتخاب کند.

هنگامی که اطلاعات تنها روی یک نود وجود داشته باشد، تضمین یکپارچگی اطلاعات آسان است؛ اما اگر اطلاعات را به صورت توزیع‌شده نگهداری کنیم، “partition tolerance” را نیز باید در نظر گرفت. یعنی باید در نظر بگیریم که اگر به هر دلیلی نودها نتوانند با یکدیگر ارتباط برقرار کنند چه اتفاقی خواهد افتاد؟ در پاسخ به این سوال tradeoffهای مختلفی را می‌توان تصور کرد. انتخاب محبوب بین برنامه‌های “cloud-native” معمولا به دست آوردن “partition tolerance” و “availability” در ازای از دست دادن “immediate consistency” است. یعنی برنامه‌های “cloud-native” از بین C و A و P، معمولا A و P را انتخاب می‌کنند، و به جای consistency از مفهوم “eventual consistency” بهره می‌برند. مثلا برای اینستاگرام ممکن است مهم باشد که همیشه در دسترس باشد و بتواند failureها را تحمل کند، ولی در یک لحظه‌ی مشخص تعداد لایک‌های یک عکس در ایران با چیزی که در برزیل دیده می‌شود متفاوت باشد.

این مفهوم احتمالا برای کسانی که بیشتر با پایگاه‌داده‌های رابطه‌ای کار کرده‌اند آشنا نباشد؛ اما همانطور که گفته شد، ویژگی بسیار قدرتمندی است که امکان scale شدن بهتر را فراهم می‌سازد. بنابراین، “eventual consistency” یک نقص نرم‌افزاری یا طراحی نیست، و هنگامی که به درستی پیاده‌سازی و استفاده شود، یک قابلیت خواهد بود.

مثال‌هایی از Eventual Consistency

اصطلاح “Eventual Consistency” نسبتا جدید است، اما ایده‌ی آن قدیمی است. یک مثال قدیمی می‌تواند DNS باشد. هنگامی که آدرس یک دامنه عوض شود، ممکن است حتا تا ساعت‌ها انتشار آن به تمام سرورهای DNS طول بکشد (چون سرورهای DNS آدرس‌ها را کش می‌کنند). پس در اینجا یک tradeoff برقرار است. آدرس‌های IP دامنه‌ها آنقدر زیاد عوض نمی‌شوند که نتوانیم عدم یکپارچگی را در ازای به دست آوردن scalability تحمل نکنیم. بنابراین تا زمانی که آدرس جدید بین همه‌ی سرورها اصطلاحا “propagate” شود، بعضی از کاربران به آدرس قبلی و بعضی به آدرس جدید مراجعه خواهند کرد.

تمام ارائه کنندگان بزرگ خدمات ابری مانند AWS، Azure و GCP، در شرایط مختلف “eventually consistent” هستند. برای مثال، بعد از فعال کردن سرویس CDN ابر AWS که “CloudFront” نام دارد، مدتی طول می‌کشد تا این سرویس در تمام نودهای آن فعال شود.

مفاهیم ACID و BASE

پایگاه‌داده‌های سنتی رابطه‌ای ۴ تضمین ACID را ارائه می‌کنند:

  • Atomicity
  • Consistency
  • Isolation
  • Durability

برای اطلاعات بیشتر می‌توانید به این لینک زیر مراجعه کنید.

این تضمین‌ها در زمانی تعریف شدند که تمام پایگاه‌های داده روی یک نود اجرا می‌شدند. برآورده کردن این ۴ تضمین، اگر اطلاعات را به صورت توزیع‌شده ذخیره کنیم بسیار پیچیده‌تر و پرهزینه‌تر خواهد شد.

بنابراین، اگر بدانیم که در اپلیکیشن ما تمام اطلاعات روی یک نود ذخیره خواهد شد، استفاده از تئوری CAP جذابیتی نخواهد داشت؛ زیرا اساسا “partition tolerance” در کار نخواهد بود. اما اگر بدانیم که پایگاه‌داده‌ی ما به صورت توزیع‌شده خواهد بود (مثلا پیاده‌سازی آن به صورت کلاستر است، یا به صورت جغرافیایی گسترده خواهد بود و از نودهای failover استفاده می‌کند)، آنگاه ناچاریم که از تئوری CAP استفاده کنیم.

این تئوری به ما می‌گوید که از سه تضمین مختلف، باید دو تای آن را انتخاب کنیم. حالت‌های ممکن عبارتند از:

  • CA
  • AP
  • CP

هر کدام از این ترکیب‌ها، رفتارهای مختلفی را به دنبال خواهد داشت. ترکیبی که روی آن تمرکز خواهیم کرد AP است.

پایگاه‌داده‌های “eventually consist” خاصیت ACID را ندارند، و به جای آن از BASE پشتیبانی می‌کنند (خاصیت بازی در مقابل خاصیت اسیدی!):

  • Basically Available
  • Soft State
  • Eventually consistent

تضمین‌های BASE معمولا در ارتباط با پایگاه‌داده‌های NoSQL مطرح می‌شود. پایگاه داده‌های NoSQL یا “Not Only SQL” برای scale بالا طراحی شده‌اند. همچنین پشتیبانی از Sharding یکی از ویژگی‌های اصلی در طراحی این پایگاه داده‌ها بوده است.

برخلاف ACID که ویژگی‌های اصلی برای انجام تراکنش‌های قابل اعتماد را تعریف می‌کند، دنیای NoSQL نیازمند ويژگی‌های دیگری برای scalability و flexibility است.

ویژگی Basically Available یعنی تضمین می‌شود که سیستم برای تمام کاربران در دسترس خواهد بود. (در اینجا برخلاف ACID، ویژگی isolation وجود ندارد.)

ویژگی Soft State یعنی مقادیری که در سیستم ذخیره شده است ممکن است به خاطر مدل "eventual consistency" تغییر پیدا کند.

ویژگی Eventually Consistent همانطور که قبلا گفته شد، یعنی اگر اطلاعاتی به سیستم اضافه شود، حالت سیستم به مرور در تمام نودها تکثیر خواهد شد. برای مثال در Hadoop، هنگامی که یک فایل روی HDFS نوشته شود، replica بلاک‌های داده در نودهای مختلف، بعد از اینکه بلاک‌های داده‌ی اصلی نوشته شدند، ایجاد می‌شوند.

ترکیب‌های مختلف CAP

مثال‌هایی از ترکیب‌های مختلف CAP:

  • سیستم‌هایی که از تکنولوژی‌های رابطه‌ای استفاده می‌کنند: این سیستم‌ها معمولا "partition tolerant" نیستند. بنابراین می‌توانند C و A را تضمین کنند.
  • سیستم‌هایی که P و A هستند: پایگاه‌داده‌های "key-value" مانند، Dynamo و CouchDB و پایگاه‌داده‌های "column store" مثل Cassandra مثال‌هایی معروفی از این ترکیب هستند.
  • سیستم‌هایی که C و P هستند: مانند HBase و Hive.

نتیجه‌گیری

تئوری CAP مبانی تئوریکی را بیان می‌کند که توضیح می‌دهد چرا نمی‌توان به صورت همزمان هم سازگاری و هم در دسترس‌ بودن را در یک سیستم توزیع‌شده داشت. یک راهکار استفاده از “eventual consistency” برای رسیدن به scalability بهتر است.

eventual consistencynosqlcloud nativebasecap theorem
شاید از این پست‌ها خوشتان بیاید