توضیح دوات: هر پایگاهدادهای که استفاده میشود، در صورتی که به صورت توزیعشده استقرار پیدا کند، یک زوج از سهگانه یکپارچگی، دسترسپذیری و تحمل تفکیکپذیری را انتخاب میکند. درک این سه مفهوم، باعث انتخاب بهتر پایگاهداده در پروژههای نرمافزاری میشود.
قضیهٔ CAP، که در سال ۲۰۰۰ توسط اریک بروئر (Eric Brewer) معرفی شد، چارچوبی اساسی برای درک موازنههایی که در طراحی سیستمهای توزیعشده باید انجام شود، ارائه میدهد.
CAP مخفف سه مفهوم یکپارچگی (Consistency)، دسترسپذیری (Availability) و تحمل تفکیکپذیری (Partition Tolerance) است و این قضیه بیان میکند که:
امکانپذیر نیست که یک سیستم ذخیرهسازی داده توزیعشده بتواند به طور همزمان هر سه این تضمینها را ارائه دهد.
- یکپارچگی (Consistency): هر عملیات خواندن یا آخرین دادهٔ نوشته شده را دریافت میکند یا با یک خطا مواجه میشود.
- دسترسپذیری (Availability): هر درخواست (خواندن یا نوشتن) بدون خطا پاسخ داده میشود، بدون تضمین اینکه دادهٔ دریافتشده حتماً جدیدترین نسخه باشد.
- تحمل تفکیکپذیری (Partition Tolerance): سیستم حتی در شرایطی که تعدادی از پیامها در شبکه بین گرهها از دست برود یا تأخیر داشته باشد، همچنان به عملکرد خود ادامه میدهد.
بررسی ۳ ستون قضیه CAP:
در این مقاله، به سه ستون اصلی قضیه CAP، موازنهها و استراتژیهای طراحی عملی برای ساخت سیستمهای توزیعشده مقاوم و مقیاسپذیر میپردازیم.
۱. یکپارچگی (Consistency)
یکپارچگی تضمین میکند که هر عملیات خواندن، جدیدترین دادهٔ نوشته شده را دریافت میکند یا با خطا مواجه میشود. این به این معنی است که تمام گرههای فعال در یک سیستم توزیعشده در هر زمان مشخص، دادهٔ یکسانی را بازمیگردانند.
- در یک سیستم توزیعشده یکپارچه، اگر دادهای روی گره A نوشته شود، یک عملیات خواندن از گره B بلافاصله تغییرات انجامشده روی گره A را منعکس میکند.
یکپارچگی برای برنامههایی که دسترسی به جدیدترین دادهها ضروری است، حیاتی است؛ مانند سیستمهای مالی که در آنها، بررسی موجودی حساب باید وضعیت بهروز حساب را نشان دهد.
۲. دسترسپذیری (Availability)
دسترسپذیری تضمین میکند که هر درخواست (خواندن یا نوشتن) یک پاسخ دریافت میکند، حتی اگر دادهٔ دریافتشده لزوماً جدیدترین نسخه نباشد. این بدان معناست که سیستم حتی در شرایطی که برخی گرهها دادههای بهروزرسانیشده را منعکس نمیکنند، همچنان عملیاتی و پاسخگو باقی میماند.
دسترسپذیری برای برنامههایی که نیاز به فعالیت مداوم دارند، مانند سیستمهای خردهفروشی آنلاین، بسیار اهمیت دارد.
۳. تحمل تفکیکپذیری (Partition Tolerance)
تحمل تفکیکپذیری به این معنی است که سیستم حتی در شرایطی که پارتیشنهای شبکهای رخ میدهد و گرهها نمیتوانند با یکدیگر ارتباط برقرار کنند، همچنان به عملکرد خود ادامه میدهد.
- پارتیشن شبکه زمانی رخ میدهد که یک خرابی شبکه باعث شود سیستم توزیعشده به دو یا چند گروه از گرهها تقسیم شود که قادر به ارتباط با یکدیگر نیستند.
در صورت وقوع پارتیشن شبکه، سیستم باید بین یکپارچگی و دسترسپذیری یکی را انتخاب کند.
تحمل تفکیکپذیری برای سیستمهای توزیعشده ضروری است، زیرا خرابیهای شبکه ممکن است رخ دهند. سیستمی که تحمل پارتیشن دارد، میتواند عملیات خود را در بخشهای مختلف شبکه حفظ کند.
تعادل CAP: انتخاب دو ویژگی از سه ویژگی
قضیه CAP بیان میکند که در صورت وجود تقسیم شبکه (Network Partition)، یک سیستم توزیعشده باید بین یکپارچگی دادهها (Consistency) و دسترسپذیری (Availability) یکی را انتخاب کند.
بیایید این سناریوها را بررسی کنیم:
CP (یکپارچگی و تحمل تقسیم شبکه):
این سیستمها اولویت را به یکپارچگی میدهند و میتوانند تقسیم شبکه را تحمل کنند، اما به بهای کاهش دسترسپذیری. در زمان تقسیم شبکه، سیستم ممکن است برخی درخواستها را برای حفظ یکپارچگی رد کند.
- پایگاههای داده رابطهای سنتی، مانند MySQL و PostgreSQL، وقتی برای یکپارچگی قوی پیکربندی میشوند، در شرایط تقسیم شبکه یکپارچگی را به دسترسپذیری ترجیح میدهند.
سیستمهای بانکی معمولاً یکپارچگی را به دسترسپذیری ترجیح میدهند، زیرا دقت دادهها در زمان مشکلات شبکه حیاتیتر از دسترسپذیری است.
به عنوان مثال، شبکه ATM بانکها: وقتی پول برداشت میکنید، سیستم باید اطمینان حاصل کند که موجودی شما در تمام گرهها (Nodes) بهدرستی بهروزرسانی شده است (یکپارچگی) تا از برداشت بیش از حد یا خطاهای دیگر جلوگیری شود.
AP (دسترسپذیری و تحمل تقسیم شبکه):
این سیستمها دسترسپذیری را تضمین میکنند و میتوانند تقسیم شبکه را تحمل کنند، اما به بهای کاهش یکپارچگی. در زمان تقسیم شبکه، گرههای مختلف ممکن است مقادیر متفاوتی برای یک داده یکسان برگردانند.
پایگاههای داده NoSQL مانند Cassandra و DynamoDB برای دسترسپذیری بالا و تحمل تقسیم شبکه طراحی شدهاند، حتی به قیمت کاهش یکپارچگی قوی.
سیستم سبد خرید آمازون برای همیشه پذیرش اقلام طراحی شده است و اولویت را به دسترسپذیری میدهد.
به عنوان مثال: وقتی کالایی را به سبد خرید خود در آمازون اضافه میکنید، این عملیات تقریباً هیچوقت با شکست مواجه نمیشود، حتی در دورههای پرترافیک مانند بلک فرایدی.
CA (یکپارچگی و دسترسپذیری):
در غیاب تقسیم شبکه، یک سیستم میتواند هم یکپارچگی و هم دسترسپذیری را فراهم کند. اما از آنجا که تقسیم شبکه در سیستمهای توزیعشده اجتنابناپذیر است، این ترکیب غیرعملی است.
مثال سیستمها: پایگاههای داده تکگرهای میتوانند هم یکپارچگی و هم دسترسپذیری را فراهم کنند، اما تحمل تقسیم شبکه را ندارند. در یک محیط توزیعشده، این ترکیب از نظر تئوری غیرممکن است.
استراتژیهای عملی طراحی
طراحی سیستمهای توزیعشده نیازمند تعادل دقیق بین این ویژگیها با توجه به نیازهای برنامه کاربردی است.
۱. یکپارچگی نهایی (Eventual Consistency)
در بسیاری از سیستمها، یکپارچگی سختگیرانه همیشه ضروری نیست. یکپارچگی نهایی میتواند تعادلی خوب ارائه دهد که در آن بهروزرسانیها نهایتاً به تمام گرهها منتشر میشوند، اما نه بلافاصله.
مثال: سیستمهایی که نیاز به یکپارچگی فوری ندارند، مانند DNS و شبکههای تحویل محتوا (CDN).
۲. یکپارچگی قوی (Strong Consistency)
مدلی که تضمین میکند پس از تأیید یک عملیات نوشتن، هر خوانش بعدی همان مقدار را برمیگرداند.
مثال: سیستمهایی که نیاز به دقت بالای دادهها دارند، مانند برنامههای مالی و مدیریت موجودی.
۳. یکپارچگی قابل تنظیم (Tunable Consistency)
این رویکرد به سیستمها اجازه میدهد تا سطوح یکپارچگی را بر اساس نیازهای خاص تنظیم کنند و تعادلی بین یکپارچگی قوی و نهایی ارائه دهند.
سیستمهایی مانند Cassandra امکان تنظیم سطح یکپارچگی در هر درخواست را فراهم میکنند و انعطافپذیری ارائه میدهند.
مثال: برنامههایی که برای عملیاتهای مختلف نیاز به سطوح متفاوتی از یکپارچگی دارند، مانند پلتفرمهای تجارت الکترونیکی که پردازش سفارش به یکپارچگی قوی نیاز دارد اما توصیههای محصول میتوانند یکپارچگی نهایی را تحمل کنند.
۴. رویکردهای مبتنی بر اجماع (Quorum-Based Approaches):
این رویکردها از رأیگیری بین گرهها استفاده میکنند تا سطح خاصی از یکپارچگی و تحمل خطا را تضمین کنند.
مثال: سیستمهایی که نیاز به تعادلی بین یکپارچگی و دسترسپذیری دارند، اغلب از الگوریتمهای اجماع مانند Paxos و Raft استفاده میکنند.
فراتر از CAP: PACELC
در حالی که CAP اساسی است، تمام سناریوها را پوشش نمیدهد. دانیل عبادی قضیه PACELC را به عنوان گسترشی معرفی کرد که زمان تأخیر (Latency) و یکپارچگی (Consistency) را بهعنوان ویژگیهای اضافی سیستمهای توزیعشده مطرح میکند.
- در صورت وجود تقسیم شبکه (P)، تعادل بین دسترسپذیری و یکپارچگی (A و C) است.
- در غیر این صورت (E)، تعادل بین زمان تأخیر (L) و یکپارچگی (C) است.
این قضیه تصدیق میکند که حتی وقتی سیستم بهطور عادی اجرا میشود، میان زمان تأخیر و یکپارچگی نیز یک تعادل وجود دارد.
قضیه CAP ابزاری قدرتمند برای درک تعادلهای ذاتی در طراحی سیستمهای توزیعشده است. موضوع، انتخاب بهترین ویژگی نیست، بلکه اتخاذ تصمیمات آگاهانه بر اساس نیازهای خاص برنامه شماست. با ارزیابی دقیق تعادلهای CAP، میتوانید سیستمهایی مقاوم و انعطافپذیر طراحی کنید که تعادلی مناسب بین یکپارچگی، دسترسپذیری و تحمل تقسیم شبکه ارائه دهند.