עבודה עם מסדי נתונים רלציוניים מתוך פונקציות קצה היא תמיד הימור על זמני תגובה. הקמת חיבור TCP, לחיצת יד של TLS ואימות מול בסיס הנתונים לוקחים לפחות חמישה סבבי תקשורת ברשת, מה שהופך כל קריאה בודדת ליקרה ומסורבלת. כדי לפתור את זה, Cloudflare השיקה את Hyperdrive כמאגר חיבורים מבוזר, והשבוע הכריזה על זמינות כללית לתמיכה בפרוטוקול MySQL לפי הפוסט הטכני של החברה. עכשיו אפשר להתחבר מתוך Cloudflare Workers למסדי MySQL או PlanetScale בלי להקים חיבור מאפס בכל בקשה, אבל מתחת למכסה המנוע מסתתרת בעיית ארכיטקטורה שעלולה להחזיר למשתמשים שלכם מידע ישן אם תסמכו על הגדרות ברירת המחדל.
מי שבונה בארכיטקטורת Serverless רגיל לחשוב ששכבת המטמון עובדת בשבילו. בפועל, השילוב של שמירת תשובות ברשת הקצה לצד כתיבה למסד נתונים מרכזי דורש כרגע מעקף ידני.
באג של אלפית האחוז
במהלך שלב הבטא, לקוח בעל נפח תעבורה גבוה דיווח על כשל חמקמק: שאילתות קריאה מסוימות החזירו באופן עקבי תשובות ריקות, למרות שהמידע היה קיים במסד. התקלה התרחשה בכ־0.001% מהמקרים בלבד, מה שהקשה מאוד על איתור עקבות הביצוע ברשת. הרמז המשמעותי היחיד היה שהבאג הופיע אך ורק במופעים שבהם מנגנון ה־Caching היה פעיל.
מתברר שההבדל בין בטא לזמינות כללית הוא פשוט 20 תיקוני באגים במעיל גשם.בלוג ההנדסה של Cloudflare
השורש התגלה בהבדלי פרוטוקול בין שרתי MySQL לדרייברים פופולריים ב־Node.js כמו mysql2. הספרייה אינה תומכת בדגל היכולת CLIENT_DEPRECATE_EOF. ללא הדגל הזה, השרת תוחם את התוצאות בחבילות EOF במקום להשתמש בחבילת OK מודרנית בסיום. ארכיטקטורת Hyperdrive בנויה משני צמתים: Client שרץ לצד ה־Worker, ו־Endpoint שיושב צמוד למסד המקור. כאשר שני הצמתים רצו באותו מרכז נתונים, הם חלקו את אותו מטמון. הצומת הפנימי שמר את המידע לפי הדגלים של Hyperdrive, בעוד ה־Worker ציפה לדגלים של הדרייבר. התוצאה הייתה חיתוך מוקדם של התשובה או תקיעה. התיקון יישר קו ושומר כעת בזיכרון המטמון גרסת בייט קנונית ואחידה בלבד, מה שהביא את שיעור ההצלחה של חיבורי הלקוח ל־99.99% לפי החברה.
מטמון בלי ביטול אוטומטי
פתרון באג הפרוטוקול מייצב את התקשורת, אבל לא פותר את עקביות הנתונים. לפי הדוקומנטציה של Hyperdrive, המערכת אינה מבצעת Cache Invalidation בעת פעולות כתיבה. אם שלחתם שאילתת עדכון באמצעות כתיבה למסד, שאילתת קריאה זהה שתגיע מיד אחריה עלולה לקבל את התשובה הישנה שנשמרה ברשת ההפצה של קלאודפלייר.
התנהגות זו שוברת לחלוטין את הציפייה לקרוא מיד את מה שנכתב הרגע, מה שמסוכן במיוחד במערכות אימות, ניהול הרשאות, יתרות כספיות או עדכון עגלות קניות. בישראל, קלאודפלייר מפעילה חוות שרתים בתל אביב ובחיפה שמספקות זמני תגובה נמוכים מול שרתים מקומיים, למשל באזור il-central-1 של AWS. המהירות הזו עובדת לרעתכם במקרה הזה: שאילתת הקריאה המקומית תחזור בתוך מילישניות בודדות עם המידע המיושן מהזיכרון המקומי, לפני שהשינוי בכלל הספיק להיתפס במסד המרוחק.
הפיצול שמציל את המידע
הדרך הנכונה לעבוד עם Hyperdrive כרגע היא לפצל את הגישה לשני bindings נפרדים בקובץ ההגדרות שלכם.
כדי לעקוף את המגבלה הזו בייצור, אי אפשר להסתמך על חיבור בודד. מגדירים חיבור אחד עם מטמון עבור קריאות סטטיות שאינן משתנות תדיר, וחיבור שני שבו המטמון מנוטרל לחלוטין עבור כתיבות, בדיקות הרשאה וקריאות רגישות.
| מאפיין | Hyperdrive עם Caching (ברירת מחדל) | Hyperdrive ללא Caching (מופרד) |
|---|---|---|
| ייעוד מרכזי באפליקציה | שאילתות קריאה חוזרות ותוכן סטטי | פעולות כתיבה, אימות ועדכון נתונים |
| שמירה ב־CDN Cache | פעיל בשכבה המקומית ובשכבת היעד | מנוטרל לחלוטין |
| עקביות קריאה אחרי כתיבה | אין, עלול להחזיר מידע ישן | מלאה וישירה מול בסיס הנתונים |
| השהיית חיבור ראשונית | 4 מילישניות ב־p90 לפי הדוקומנטציה | 4 מילישניות ב־p90 לפי הדוקומנטציה |
לא הייתי ממהר לבטל את הפיצול הזה עד שקלאודפלייר תציג מנגנון מובנה שמנקה את המטמון בעת הרצת פקודות כתיבה, או תמיכה רשמית ב־Prepared Statements עבור MySQL שלא נתמכת כרגע.
בינתיים, שני מאגרי חיבורים בקוד הם המחיר שצריך לשלם על יציבות.
מקורות
- Inside Hyperdrive: How we solved a rare Hyperdrive MySQL caching bughttps://blog.cloudflare.com/hyperdrive-mysql/
- PlanetScale Postgres & MySQL · Cloudflare Hyperdrive docshttps://developers.cloudflare.com/hyperdrive/planetscale
- Posts tagged "Developers" — Cloudflare Bloghttps://blog.cloudflare.com/tag/developers
- Cloudflarehttps://weba.co.il/tools/cloudflare/
- Cloudflare Workershttps://weba.co.il/tools/cloudflare-workers/
- Serverlesshttps://weba.co.il/glossary/serverless/
הידיעה נכתבה מהמקורות שלמעלה בתאריך הפרסום, וכל טענה בה נבדקה מולם. מצאתם טעות? כתבו.