ניתוב תעבורת וידאו באזור אסיה-פסיפיק באמצעות etcd

פלטפורמת סטרימינג של וידאו המשרתת שמונה שווקים באזור אסיה-פסיפיק הפסיקה טעות ניתוב חוזרת על ידי העברת הגדרות ספציפיות לאזור לתוך etcd. זמן הפצת שינויי הניתוב ירד לכשנייה אחת. עורכים יכלו כעת להגביר מאגר מוזיקה למשך כמה שעות מבלי לגעת בקוד, והפלטפורמה הפסיקה לשלוח לצופים מדרום קוריאה את הזרם (feed) של טוקיו.

מדוע הגישה הישנה נכשלה

כל נתב קרא שלושה ערכים עבור כל בקשה: מאגר הטרנדים (trending pool), ה-tokenizer הספציפי לשפה, ושרשרת גיבוי (fallback chain). החלטות עסקיות — קידום אמן חדש, תגובה להפרעה אזורית, בדיקת אלגוריתם המלצות — הניעו את הערכים הללו, ולא שינויי קוד.

בתחילה, כל פריסה (deployment) כללה קובץ JSON עם טבלת הניתוב. במהלך תקלה, מהנדס בתור (on-call) ערך את הקובץ בצומת (node) אחת כדי להפנות את התעבורה למאגר גיבוי, אך מעולם לא עדכן את שבעת הצמתים האחרים. נוצר מצב של סטיית הגדרות (config drift): שמונה מדינות הריצו טבלאות שונות, ולא היה מקור יחיד שאימת את ה"אמת". הבאג ששלח צופים מסיאול לטוקיו נמשך כי הקוד נשאר זהה; רק ההגדרות הנסתרות היו שונות.

בחירת etcd כמקור האמת היחיד

הצוות השווה בין שלוש אפשרויות:

  • SQLite/MySQL – היה מאלץ כל נתב לבצע שאילתות (poll) למסד נתונים, מה שמוסיף שיהוי (latency) או מציף שאילתות.
  • Consul – כלי איתן לגילוי שירותים (service-discovery), אך הפלטפורמה לא נזקקה לתכונות ה-mesh המלאות שלו.
  • etcd – מאגר מפתח-ערך (key-value store) בעל עקביות חזקה (strongly consistent) עם פרימיטיב watch שמתריע בפני לקוחות ברגע שמפתח משתנה.

תכונת ה-watch היא שנטתה את המאזניים. במקום שכל נתב ישאל שוב ושוב "האם משהו השתנה?", הנתבים נשארו במצב המתנה עד ש-etcd דחף עדכון. תעבורת הרשת המיותרת נעלמה וכל מופע (instance) למד על השינוי בו-זמנית.

תבניות ששומרות על בטיחות המערכת

etcd לבדו לא פתר את כל הסיכונים. המהנדסים הוסיפו שלוש תבניות משלימות:

  1. Leases – עורך יכול להגדיר הגברה זמנית (למשל, הגדלת המשקל של מאגר K-pop למשך שש שעות). ה-lease פג באופן אוטומטי, כך שההגברה נעלמת ללא צורך בביטול ידני (rollback).
  2. Compare-and-swap (CAS) – כאשר שני אנשים עורכים את אותה הגדרה בו-זמנית, CAS נכשל בצורה מפורשת עבור אחד מהם, מה שמונע דריסות שקטות.
  3. Sidecar process – PHP מתקשה עם חיבורים ארוכי טווח. תהליך sidecar קטן ב-Go על כל מכונה צופה ב-etcd וכותב תמונת מצב (snapshot) של טבלת הניתוב לקובץ בזיכרון משותף (/dev/shm). PHP קורא את הקובץ המקומי הזה, ובכך נמנע מכל עיגול רשת (network round-trip) במהלך טיפול בבקשה.

חוסן המובנה בארכיטקטורה

העיצוב החדש מוסיף מספר רשתות ביטחון:

  • Zero-latency reads – נתיב הביצועים החם (hot path) של PHP קורא מהזיכרון המקומי, כך שבקשות לעולם לא נתקעות בהמתנה למאגר מרוחק.
  • Graceful degradation – אם etcd קורס, הנתבים ממשיכים להגיש את ההגדרות התקינות האחרונות שהיו ידועות להם, מה שמונע השבתה פתאומית.
  • Reliable updates – ה-sidecar מטפל בלוגיקת התחברות מחדש ומבטיח ששום שינוי לא יתפספס, גם אם החיבור ל-etcd מתנתק זמנית.

מה השתנה בשטח

לאחר המעבר, הצוות ראה ירידה חדה בתקלות שנגרמו מנתוני ניתוב מיושנים או לא תואמים. קונסולה אחת בלבד מציגה כעת את ההגדרות הנוכחיות, וכל עריכה מופצת לכל שמונה האזורים תוך שנייה. הגברות זמניות מתנקות מעצמן כשה-lease שלהן פג, מה שמסיר את שלבי הניקוי הידניים שבעבר הובילו לשגיאות אנוש.

נקודת מבט נגדית: המחיר של sidecar

הוספת sidecar משמעותה תהליך שני לכל שרת וסביבת ריצה (runtime) של Go בתוך מחסנית (stack) מבוססת PHP. מפעילים מסוימים חוששים מצריכת זיכרון נוספת ומהצורך לנטר binary נוסף. בפועל, טביעת הרגל של ה-sidecar נותרת צנועה, והרווחים בחוסן — במיוחד ההבטחה ש-PHP לעולם לא יחסום קריאה לרשת — עולים על העלות התפעולית.

מה כדאי לעקוב אחריו בהמשך

צוותים המנהלים שירותים רב-אזוריים צריכים לנטר:

  • etcd health metrics – שכבת הניתוב נשענת על מאגר יחיד; עקבו אחר סטטוס ה-quorum וזמני השיהוי (latency).
  • Lease expiration handling – התאימו את זמני ה-lease לחלונות העסקיים; leases ארוכים מדי משאירים הגברות מיושנות פעילות.
  • Scaling the watch load – ככל שמספר הנתבים גדל, גם מספר חיבורי ה-watch גדל; תכננו קיבולת עבור שרתי etcd בהתאם.

שורה תחתונה

עבור כל שירות הזקוק לשינויי הגדרות מהירים ומתואמים על פני אזורים רבים, הפרימיטיבים watch, lease ו-transaction של etcd מציעים חלופה קלה ובעלת עקביות חזקה (strongly consistent) להגדרות מבוססות קבצים או ל-meshes כבדים. הפיכת ההגדרות למאגר מבוסס-דחיפה (push-driven) ובעל ניקוי עצמי ביטלה סוג שלם של תקריות והעניקה לפלטפורמה שליטה בזמן אמת על לוגיקת הניתוב שלה.