حافظه کش تو سیستم‌های پخش‌شده: چطور همیشه همه‌چی هماهنگه؟

ببین، این روزا خیلی از شرکت‌ها و استارتاپ‌ها واسه مدیریت اطلاعاتشون سراغ سیستم‌های پخش‌شده یا همون “Distributed Systems” میرن. حالا سیستم پخش‌شده یعنی چی؟ یعنی اطلاعات رو به جای این که فقط تو یه کامپیوتر ذخیره کنی، بین چندتا سرور و کامپیوتر مختلف پخش می‌کنی تا هم امنیت بیشتر شه، هم سرعت بالاتر بره.

حالا فرض کن یه سایت بزرگ داری با کلی کاربر که دائم دارن درخواست میدن. اطلاعات و درخواست‌ها هم تو دیتابیس‌هایی ذخیره میشه که بهشون میگن “Relational Database Management Systems” یا همون سیستم مدیریت دیتابیس رابطه‌ای. مثل اونایی که توش جدول و رکورد و اینجور چیزا داری. این دیتابیس‌ها هسته اصلی ذخیره‌سازی این سیستم‌ها هستن و تقریباً همه میکروسرویس‌ها (یعنی بخش‌های کوچیک ولی مستقل یه برنامه بزرگ) بهش وصلن.

مشکل اینجاست که گاهی موقع پردازش درخواست‌ها، کل زمان پردازش بیشتر از اون مقداری میشه که ما به مشتریانمون قول دادیم. این مقدار قول داده شده رو بهش میگن “Service Level Agreement” یا SLA. یعنی مثلاً گفتیم هر درخواست باید نهایتاً تو ۲ ثانیه جواب داده بشه، ولی گاهی طول می‌کشه و این خوب نیست!

اینجاست که “Cache” وارد بازی میشه. کش یه جور حافظه است که اطلاعات پر استفاده رو تو خودش نگه می‌داره تا دیگه مجبور نباشیم هر بار همه‌چیز رو از دیتابیس اصلی بخونیم. خلاصه، کش مثل راه میانبر واسه دسترسی سریع‌تر به اطلاعاته.

اما وای به روزی که تعداد سرور و سرویس‌ها زیاد بشه! دیگه هماهنگ نگه داشتن اطلاعات بین همه کش‌ها میشه یه دردسر واقعی. فرض کن یه کاربری یه اطلاعاتی رو عوض می‌کنه، ولی هنوز کش یکی از سرورا آپدیت نشده! این یعنی ممکنه یکی دیتا قدیمی ببینه و یکی جدید.

اینجا بحث “Consistency” یا همون هماهنگی اطلاعات پیش میاد. مدل‌های مختلفی واسه هماهنگ نگه داشتن کش وجود داره. ولی ما اینجا دنبال یه مدل هماهنگی قوی هستیم یا همون “Strong Consistency”. Strong Consistency یعنی هر کسی هر جایی اطلاعات رو خوند، همیشه جدیدترین نسخه رو می‌بینه، نه چیز قدیمی‌تر. واسه همین این مدل خیلی مطمئنه، ولی پیاده‌سازیش سخت‌تره.

خیلی سیستم‌های پخش‌شده سراغ مدل‌های ساده‌تر مثل eventual consistency میرن که یعنی بالاخره همه کش‌ها آپدیت میشن، اما نه فوراً. ولی خب، این ممکنه تو بعضی سناریوها مشکل درست کنه، مثل همون مثالی که یکی دیتا جدید می‌بینه و یکی نه.

حالا سوال اینه: چجوری می‌تونیم یه کش پخش‌شده با مدل هماهنگی قوی بسازیم که همه‌چی همیشه آپدیت باشه و تاخیر هم نداشته باشیم؟

راه‌حل اینه که بیایم از “Consensus Algorithm” استفاده کنیم. یعنی الگوریتم اجماع. اجماع یعنی قبل از این که اطلاعات تو کل شبکه ذخیره بشه، همه سرورها باید به یه نظر مشترک برسن که چی ذخیره بشه و بعد همه‌شون با هم آپدیت شن. از جمله معروف‌ترین الگوریتم‌های اجماع میشه به Paxos و Raft اشاره کرد. این الگوریتم‌ها معمولاً واسه هماهنگ نگه داشتن دیتا در سیستم‌های پخش‌شده استفاده میشن.

این ایده می‌تونه کمک کنه هم SLA رو رعایت کنیم، هم اطلاعات همیشه درست و جدید باشه. اما خب، ساختن همچین سیستمی آسون نیست و دردسرایی هم داره، مثلا شاید سرعت سیستم یه کم بیاد پایین چون باید همه سرورها صبر کنن تا اجماع انجام شه.

توی سیستم‌هایی که الان داریم، معمولاً یا کش قوی و سریع داریم ولی هماهنگی ضعیفه، یا هماهنگی قوی داریم ولی سرعت پایین میاد. هنوز یه راه‌حل کامل که هم سرعت و هم هماهنگی رو با هم داشته باشه پیدا نکردیم.

واسه همینه که ایده این مقاله اینه: بیایم یه کش پخش‌شده طراحی کنیم که از الگوریتم اجماع کمک می‌گیره تا مطمئن شیم هم داده‌ها همیشه هماهنگن، هم سرعت قابل قبولی داره و می‌تونه با SLAهای سخت و سنگین امروزه کنار بیاد.

در نهایت باید واسه این سیستم معماری طراحی کنیم که بتونه همه اینا رو مدیریت کنه: ارتباط بین کش و دیتابیس اصلی، هماهنگ نگه‌داشتن همه سرورها، و پاسخ سریع به درخواست‌ها.

خلاصه که موضوع بحث ما الان اینه: سیستم کشی بسازیم که پخش‌شده است، ولی بر خلاف اکثر کش‌های پخش‌شده فعلی، همیشه اطلاعاتش دقیق و به‌روز باشه. اونم با کمک الگوریتم اجماع!

اگه دوست داری بدونی بیشتر چطوری این سیستم طراحی میشه و چه چالش‌هایی داره، حتما درباره معماری‌های کش امروزی و الگوریتم‌های اجماع بیشتر سرچ کن؛ کلی مطلب جالب پیدا می‌کنی!
منبع: +