
در این مقاله میخوام که با یکی دیگر از قضیه ها و مفاهیمی که در طراحی سیستم (System Design) مفید هست بدانیم، صحبت کنیم و اون هم تئوریCAP هست. تئوریCAP برای سیستم توزیعشده (Distributed System) کاربرد داره که با استفاده از مفهوم مقیاس پذیری افقی (Horizontal Scaling) که در مقاله مقیاس پذیری (Scaling) در مورد این نوع ها از Scaleup صحبت کردیم، ایجاد میشه.
سیستم توزیعشده (Distributed System) یعنی مجموعهای از چند کامپیوتر (Node یا Server) که از طریق شبکه به هم وصل شدن و با هم مثل یک سیستم واحد کار میکنن.
تئوری CAP از به سه بخش تقسیم میشه که عبارتند از:
یکپارچگی داده (Consistency) یعنی تمام داده ها در تمام نود ها یکسان و یکپارچه شود. فرض کنید که یک نرم افزار بانکی دارید که بر روی 3 نود اورده شده بالا و کاربران در زمان ارسال درخواست به وسیله لود بالنسر به یکی از نود ها منتقل می شوند، اگر کاربر در هنگام پرداخت به یک نود منتقل شود و فاکتوری را پرداخت کند و جهت مشاهده وضعیت فاکتور به یک نود دیگر منتقل شود که تراکنش پرداخت کاربر در اون نباشد، باعث می شود با عدم یکپارچگی داده روبرو شوید. اینجاست که Consistency کاربرد دارد و باید در هرلحظه داده ها بین نود ها سینک شوند.
Availability یعنی در دسترسی بودن سرویس، فرض کنید که 3 نود دارید که کاربران با توجه به ترافیک روی هر کدام از نود ها بین آن ها جابه جا می شوند، حالا در فرایند یکی از نود ها مشکلی پیش امده که دیگه نمیتونه جواب گو باشه و در دسترس نیست، در این حالت اگر سیاست شما این باشد که در این جور موقعیت ها کاربر از خرابی سیستم اطلاع پیدا نکند Availability کاربرد پیدا میکند و اون نود مشکل دار به صورت خودکار و یا دستی باید از خط خارج شود و کاربران به نود های استیبل منتقل شوند.
تابآوری در برابر قطعی شبکه (Partition tolerance) یعنی وقتی بخشی از شبکه قطع شد (مثل وقتی که چند سرور با هم ارتباط ندارن)، سیستم همچنان به کار خودش ادامه بده و از کار نیفته.

ویژگی هایی که در ادامه میگم بسته به سیاست ها و نوع پروژه بایستی انتخاب کرد و این هم درنظر داشته باشید که هیچ وقت سه ویژگی CAP یعنی هم یکپارچگی (Consistency) و هم تحمل قطعی شبکه (Partition tolerance) و هم Availability، را نمی شود اعمال و رعایت کرد.
ممکن هست که سیاستتون این باشه که داده ها بین نود ها سینک بشند و همواره یکسان باشند و در صورتی که شبکه مشکلی داشت سیستم به روال عادیش ادامه بده ولی یک بدی که این نوع ویژگی داره کندی سیستم و منتظر ماندن درخواست کاربر هست. چون که سیستم تا زمانی که نود ها خودشون رو آپدیت و سینک نکنند کاربران باید منتظر در دسترس بودن سیستم باشند.
نرم افزار ها و پروژه هایی که در آن می شود این ویژگی درنظر گرفت و استفاده کرد عبارتند از:
MongoDB (با تنظیم مناسب)
HBase
Zookeeper
Etcd
بانکها (برای جلوگیری از دوبار برداشت پول)
اپلیکیشنهایی که دقت داده خیلی مهمه (مالی، حسابداری، رایگیری)
ممکن هست که سیاستتون این باشه که نود ها آپدیت نشند ولی همواره در دسترس باشند و کاربر متوجه قطعی یکی از نود ها نشه. ولی یک بدی که این نوع ویژگی داره داده ها بین نود ها سینک و اپدیت نمی شود.
نرم افزار ها و پروژه هایی که در آن می شود این ویژگی درنظر گرفت و استفاده کرد عبارتند از:
Cassandra
Couchbase
DynamoDB
Redis (با replication)
سیستمهای پربازدید که delay مهمتر از دقت لحظهایه
اپهایی مثل پیامرسانها، شبکههای اجتماعی، فروشگاههای آنلاین با caching بالا
ممکن هست که سیاستتون این باشه که سیستم همواره در دسترس باشد و داده ها بین نود ها باهم سینک شوند. ولی بدی این ویژگی این هست که هیچ وقت نمیشه تضمین داد که مشکل شبکه ای یک سیستم نداره، بنابراین Partition Tolerance در عمل اجتنابناپذیر است.
نرم افزار ها و پروژه هایی که در آن می شود این ویژگی درنظر گرفت و استفاده کرد عبارتند از:
سادهترین دیتابیسهای تکسرور مثل PostgreSQL یا MySQL در حالت بدون replication
سیستمهای داخل یک ماشین یا LAN بدون ریسک قطع ارتباط
پروژههای ساده، MVPها، اپهای تکسرور، اپلیکیشنهای داخلی شرکت
هرچند قضیه CAP یک مفهوم بنیادی در طراحی سیستمهای توزیعشده است، اما در عمل محدودیتهایی هم دارد که نمیشه ازشون گذشت و بهتر که درنظر گرفت:
سادهسازی بیش از حد:
CAP فقط سه ویژگی کلی را بررسی میکند و بسیاری از فاکتورهای مهم مانند تأخیر شبکه، هزینه ارتباط بین نودها، تحمل خطا و مسائل امنیتی را در نظر نمیگیرد.
مدل باینری:
این قضیه ویژگیها را به صورت مطلق (همه یا هیچ) فرض میکند، در حالی که در واقعیت، اکثر سیستمها ترکیبی از درجات مختلف Consistency و Availability را ارائه میدهند.
تمرکز بر پارتیشن:
CAP فقط شرایطی را پوشش میدهد که Partition اتفاق بیفتد، در حالی که در عمل، بسیاری از مشکلات شبکهای کوتاهمدت هستند و نیاز به استراتژیهای انعطافپذیرتری دارند.
نادیده گرفتن مفاهیم جدید:
امروزه بسیاری از سیستمهای مدرن از مدلهای Consistency ضعیفتر (مثل Eventual Consistency) یا تکنیکهای پیشرفتهای مثل Consensus Algorithms برای حل مشکلات CAP استفاده میکنند.
به طور کلی، CAP یک چارچوب ذهنی ساده و مفید برای شروع طراحی سیستمهای توزیعشده است، اما نباید تنها مبنای تصمیمگیری معماری باشد. باید سایر فاکتورهای عملیاتی و نیازهای خاص پروژه را هم در نظر گرفت.
ممنون که تا این لحظه همراه من بودید. اگر سوال، انتقاد و یا پیشنهادی داشتید خوشحال میشم در بخش کامنت های این مطلب با من درمیون بزارید.