سخنرانان: Prudhviraj Karumanchi & Vidhya Arvind
رویداد: QCon San Francisco 2024
لینک ویدئو: https://www.infoq.com/presentations/netflix-write-ahead-logging/
وقتی سیستمی به ابعاد نتفلیکس میرسد که صدها میلیون کاربر، هزاران سرویس و دهها فناوری ذخیرهسازی مختلف از Cassandra تا کشهای توزیعشده دارد، سوالهای سادهای مثل «مطمئنیم این داده واقعاً ذخیره شد؟» یا «چرا این دو نسخه از داده با هم نمیخوانند؟» به مسائل معماری تمامعیار تبدیل میشوند. در این ارائه از QCon سانفرانسیسکو ۲۰۲۴، پرودویراج کارومانچی و ویدیا آرویند، دو مهندس ارشد پلتفرم داده نتفلیکس، توضیح میدهند که چطور با ساختن یک سرویس عمومی «ثبت پیشنویس» (Write-Ahead Log یا WAL) در سطح پلتفرم، مجموعهای از دردناکترین مشکلات سیستمهای توزیعشده مانند ازدسترفتن داده، واگرایی نسخهها و جهشهای چندپارتیشنی را یک بار برای همه تیمها حل کردهاند. چیزی که این ارائه را خاص میکند این است که یک ایده قدیمی و اثباتشده از دل پایگاههای داده را بیرون کشیده و بهعنوان یک بلوک معماری مستقل و قابل استفاده مجدد بازآفرینی کرده است.
سخنرانان از صورتمسئله شروع میکنند: در مقیاس نتفلیکس، خرابی نه استثنا بلکه وضعیت عادی است. نوشتنی که بهظاهر موفق بوده ممکن است در یکی از مقصدها گم شود؛ دادهای که باید هم در پایگاه داده اصلی و هم در کش و هم در ایندکس ثانویه بنشیند، ممکن است فقط در بعضی از آنها بنشیند؛ و به مرور زمان «آنتروپی» که همان واگرایی خاموش بین نسخههای مختلف یک داده است، سیستم را میخورد. راهحل سنتی این بوده که هر تیم برای خودش منطق retry و صف و ترمیم بنویسد؛ نتیجه، دهها پیادهسازی ناسازگار از یک مسئله واحد بود.
ایده مرکزی ارائه ساده و قدرتمند است: هر جهش (Mutation) پیش از اعمال، ابتدا در یک لاگ بادوام ثبت شود و سپس از آنجا با تضمین، به مقصد یا مقصدهایش برسد. معماری سرویس WAL از چند جزء تشکیل شده که تفکیک مسئولیت تمیزی دارند: پردازشگر پیام که جهشها را دریافت و در صف بادوام ثبت میکند، مصرفکنندهای که آنها را به مقصدها میرساند، و یک Control Plane برای پیکربندی و پایش. نکته معمارانه کلیدی، «مقصدهای اتصالپذیر» (Pluggable Targets) است: همان لوله واحد میتواند جهشها را به Cassandra، به کش، به ناحیه جغرافیایی دیگر یا به هر ذخیرهگاه دیگری برساند؛ یعنی WAL از یک ابزار دوام داده، به ستون فقرات تکثیر بینسیستمی و بازسازی داده تبدیل میشود. بخش قابلتوجهی از ارائه هم صادقانه به حالتهای خرابی خود این سیستم میپردازد: هجوم ناگهانی ترافیک، مصرفکنندههای کند، پیامهای سمی و خطاهای ماندگار، و سازوکارهایی مثل صفهای تأخیری و جداسازی، که برای هر کدام طراحی شدهاند. بهای این معماری هم پنهان نمیشود: سازگاری نهایی بهجای فوری، کمی تأخیر اضافه و هزینه عملیاتی یک سرویس جدید.
دو درس از این ارائه برای من پررنگتر از بقیه بود. اول، قدرت «انتزاع در سطح پلتفرم»: نتفلیکس بهجای آنکه به صد تیم آموزش بدهد چطور نوشتن مطمئن پیاده کنند، مسئله را یک بار در قالب سرویسی با قرارداد ساده حل کرده است. این همان تفکری است که پشت مفهوم «مسیر هموار» (Paved Path) قرار دارد و بهگمانم مهمترین الگوی معماری سازمانی دهه اخیر است: پیچیدگی را به داخل پلتفرم ببر تا تیمهای محصول با ذهنی آزاد کار کنند. دوم، بازیافت ایدههای کهنه: WAL دهههاست قلب هر پایگاه دادهٔجدی است؛ کاری که نتفلیکس کرده «اختراع» نیست، «تغییر مقیاسِ» یک الگوی اثباتشده است — از داخل یک پروسه به کل یک اکوسیستم. این نگاه برای ما هم آموزنده است: قبل از ساختن راهحل بدیع، بپرسید کدام الگوی چهلساله دارد همین مسئله را در لایهای دیگر حل میکند. اگر بخواهم نقدی هم بکنم، این است که ارائه درباره هزینه نگهداری چنین سرویسی برای سازمانهای کوچکتر کم میگوید؛ چیزی که خودشان هم تلویحاً میپذیرند این است که این معماری وقتی میارزد که تعداد مصرفکنندههایش از حدی بگذرد.
شاید هیچوقت WAL اختصاصی نسازید، اما الگوهای این ارائه در مقیاسهای بسیار کوچکتر هم کار میکنند. اگر جایی در سیستم شما یک نوشتن باید به چند مقصد برسد، بهجای نوشتن مستقیم و دعاکردن، الگوی مشابهی مثل Transactional Outbox یا یک صف بادوام میانی بگذارید تا تحویل تضمینشده و قابلتکرار شود. برای بازیهای آنلاین این سناریو کاملاً ملموس است: رویدادهای اقتصاد درون بازی (خرید، جایزه، ارتقا) دقیقاً همان جهشهای حساسی هستند که نه باید گم شوند و نه دو بار اعمال شوند؛ ترکیب لاگ بادوام با مصرفکننده idempotent همان تضمینی را میدهد که نتفلیکس برای دادههایش میخواهد. الگوی «ترمیم آنتروپی» هم مستقیم قابل استفاده است: یک job دورهای که نسخههای مختلف داده را مقایسه و واگراییها را گزارش یا ترمیم میکند، برای هر سیستمی که کش یا ایندکس ثانویه دارد، بیمهنامه ارزانی است.
این ارائه نمونه خوبی از معماری «بالغ» است: نه شیفته فناوری جدید، نه اسیر پیچیدگی نمایشی؛ فقط بازشناسی یک الگوی کلاسیک و بالابردن آن به سطحی که کل سازمان از آن سود ببرد. درسهای کلیدی: دوام و سازگاری داده را به امید کد اپلیکیشن رها نکنید و آن را به زیرساختی صریح بسپارید؛ مسائل تکرارشونده را یک بار و در سطح پلتفرم حل کنید؛ برای خرابی مصرفکنندهها و پیامهای سمی از روز اول طرح داشته باشید؛ و بین سازگاری فوری و تابآوری، آگاهانه و صریح انتخاب کنید. برای هر مهندسی که با دادههای حیاتی در سیستمهای توزیعشده سروکار دارد، این پنجاه دقیقه سرمایهگذاری پرسودی است.
اين مطلب، بخشی از تمرينهای درس معماری نرمافزار در دانشگاه شهيد بهشتی است.