پیکربندی روتر ناحیه ویدیو با استفاده از etcd Watches و Leases
ما با استفاده از یک نقشه ناحیه (region map)، بینندگان را به نزدیکترین edge ویدیو هدایت میکنیم. این نقشه به ما میگوید که برای ترافیک خاص، از کدام edge pool استفاده کنیم.
برای مدتی طولانی، این نقشه را در یک فایل پیکربندی PHP نگه میداشتیم. ما آن را با هر بهروزرسانی اپلیکیشن مستقر (deploy) میکردیم. زمانی که یکی از شرکای CDN در سنگاپور دچار قطعی شد، متوجه شدیم که این طراحی بدی بوده است. تغییر یک قانون به معنای استقرار کامل در تمام گرهها (nodes) بود. در طول آن فرآیند استقرار، ترافیک همچنان به یک pool از کار افتاده ارسال میشد. برای ویدیو، این تأخیر به این معناست که کاربر یک spinner میبیند و تب را میبندد.
ما نقشه ناحیه را از فایلهای استقرار به etcd منتقل کردیم. اکنون، تغییرات را به صورت اتمیک (atomic) انجام میدهیم و بهروزرسانیها را در کمتر از یک ثانیه منتشر میکنیم.
چرا etcd بهتر از polling عمل میکند:
• Watches: روترها یک watch باز نگه میدارند. آنها بلافاصله پس از ثبت (commit) مقادیر جدید، آنها را دریافت میکنند. این روش سریعتر از استفاده از تایمر است. • Leases: ما کلیدها را به یک TTL متصل میکنیم. اگر فرآیند بررسی سلامت (health-checker) از کار بیفتد، کلید به طور خودکار ناپدید میشود. این کار باعث مدیریت failoverها بدون دخالت دستی میشود. • Atomic Transactions: شما میتوانید یک نقشه کامل را در یک حرکت جایگزین کنید. این کار از مشاهده حالتهای نیمهبهروزرسانی شده توسط روترها جلوگیری میکند.
ما از etcd فقط برای دادههای control-plane استفاده میکنیم. قوانین مسیریابی و سلامت poolها در etcd باقی میمانند. متادیتای ویدیو در SQLite میماند. این جداسازی باعث میشود hot path سریع باقی بماند.
طراحی ما از یک پیشوند کلید نسخهبندی شده مانند /dw/v1/routes/ استفاده میکند. این کار به ما اجازه میدهد در طول مهاجرتها، schemaهای v1 و v2 را در کنار هم اجرا کنیم.
روتر دو مورد را با هم ترکیب میکند:
- Intent: جایی که اپراتورها میخواهند ترافیک به آنجا برود (زیردرخت routes).
- Reality: کدام poolها در واقع سالم هستند (زیردرخت health).
اگر یک کلید سلامت به دلیل انقضای lease ناپدید شود، روتر به طور خودکار به fallback pool تغییر وضعیت میدهد.
برای سریع نگه داشتن مسیر درخواست، ما در طول درخواست ویدیو، etcd را فراخوانی نمیکنیم. روتر Go ما etcd را watch میکند و یک اسنپشات محلی را در فایلی در /dev/shm مینویسد. ورکرهای PHP ما این فایل را از RAM میخوانند. این کار تصمیمگیری مسیریابی را به یک جستجوی ساده در حافظه محلی تبدیل میکند.
درسهای آموخته شده:
• بستن کانالهای watch: اگر watch شما قطع شد، همیشه آن را دوباره ایجاد کنید. • Compaction: اگر برای مدت طولانی قطع هستید، یک اسنپشات تازه بگیرید. • Leaseها به اتصال نیاز دارند: قطع شدن اتصال میتواند باعث انقضای یک lease شود. برای جلوگیری از این اتفاق از یک کلاستر etcd استفاده کنید. • hot path را محلی نگه دارید: هرگز برای هر درخواست کاربر، یک فراخوانی شبکه به etcd انجام ندهید.
انتقال نقشه ناحیه به etcd، پاسخگویی دستی به حوادث را به یک سیستم self-healing تبدیل کرد.
