מדוע פלטפורמת AI SaaS נתקלת בתקרה בעת צמיחה
כל עוד מספר הדיירים קטן, הפלטפורמה נשענת על מתאר משותף אחד: תור אחד לעיבוד בקשות למודל, מאגר מחשוב אחד, מסד נתונים משותף עם הגדרות לקוחות. עמידות לתקלות וחימום מתקבלים «עבור כולם בבת אחת», ובקשה כבדה של לקוח אחד נכנסת לאותו תור כמו בקשות קלות של האחרים.
התמיכה מבחינה בכך ראשונה: זמן התגובה באחוזון ה-95 גדל מהר יותר ממספר הלקוחות, כי הוספת דייר לא מוסיפה בידוד אלא רק מאריכה את התור המשותף. לקוח בודד עם זינוק בעומס גורר אחריו ירידה בביצועים אצל כולם — שכן רועש קלאסי, רק בלי אפשרות להגביל מישהו.
השכבה השנייה — שחרור עדכוני מודלים. גרסה חדשה מועברת על כל הלקוחות בבת אחת, כי אין מנגנון ניהול גרסאות ופריסה הדרגתית: מהנדס בונה מחדש את הארטיפקט ידנית, מניח אותו באחסון משותף ומפעיל מחדש את השירות.
חלון הפריסה וחלון החזרה חופפים, אי אפשר לבדוק איכות על מקטע אחד, וכל שגיאה במשקלים נראית מיד אצל כל בסיס הלקוחות. בנוסף התנעות קרות: עד שהמודל מחומם, הבקשות הראשונות של כל דייר נכשלות בטיימאאוט.
השלישי והיקר ביותר — צוואר בקבוק בתחזוקה. מגבלות, רמות תעריף והגדרות דייר נמצאים בסקריפטים ומתוקנים ידנית במסד; מדדים נאספים בזרם משותף בלי פילוח לפי לקוחות. תקרית אצל דייר אחד מכבה אחרים בשרשרת, והניתוח אורך שעות, כי אין דרך להפריד נתונים ועומס של אחרים. נסביר איך זה נסגר — בידוד מתארים, ניהול גרסאות של מודלים ושחרור עדכונים אוטומטי.
ריבוי דיירים ובידוד נתונים: השפעה מדידה
כל עוד הלקוחות חיים במסד משותף עם סימן בעלים בטבלאות, כל שינוי סכימה הופך לסיכון משותף: מיגרציה עבור לקוח אחד מועברת על כולם, ושכן עם עומס שיא מפיל את זמן התגובה אצל האחרים. המחיר של סכימה כזו — אישורי שחרור ארוכים ותקריות שמכבות את כל המתאר בבת אחת.
אנחנו מפזרים את הלקוחות בין מרחבי שמות ואחסון נפרד: כרכים מוצפנים משלהם, מפתחות משלהם, ניתוב בקשות לפי מזהה לקוח. משותפים נשארים רק שכבות השירות — שער, תור משימות, איסוף מדדים. הנתונים לא מצטלבים לא בזיכרון, לא בדיסק ולא בגיבויים, ולכן לקוח אחד פיזית לא יכול לפגוע באחר.
ההשפעה מדידה בשלושה מדדים. זמן שחרור השינויים מתקצר פי כמה: עדכון מועבר על לקוח קנרית נפרד ומופרס באופן עצמאי, בלי עצירה משותפת לאישור. חלק התקלות שמשפיעות בבת אחת על כמה לקוחות יורד לאפס — התקלה מתמקמת בגבולות מתאר אחד, והאחרים ממשיכים לעבוד.
מתאר שירות אחיד נשמר עם זאת: מדיניות גישה משותפת, כללים אחידים לגיבוי ולשחזור, מעקב מקצה לקצה על כל הלקוחות.
אשכול Kubernetes עם הפרדה לפי מרחבי שמות נותן לכל אחד סט כלים זהה, והתחזוקה נעשית צפויה: המהנדס רואה אצל מי זמן התגובה צונח ומתקן זאת נקודתית, בלי להוציא מכלל פעולה את האחרים.
חיוב וחשבונאות צריכה: אפשרויות של סכימות תעריף
מודל תעריף הוא לא מחירון, אלא חוזה בין חשבונאות הצריכה לבין החישובים. הוא קובע מה בדיוק נכנס ליומן האירועים: זמן עבודת סשן, מספר בקשות שעובדו, נפח נתונים בכניסה וביציאה, משאבי מחשוב תפוסים.
טעות ברמה הזו היא היקרה מכולן: אם יחידת החשבונאות נבחרה לא נכון, יהיה צורך לעשות מחדש גם את חישוב המגבלות, גם את החיוב וגם את הדיווח ללקוח.
לרוב הקיצוניות לא עובדות בצורתן הטהורה. מנוי עם מכסות נותן צפיות לשני הצדדים, אבל אם המכסה נבחרה באקראי, הלקוח או משלם יותר מדי על זמן אפס, או נתקל במגבלה בשיא העומס. תשלום לפי צריכה הוא הוגן, אבל קשה לחיזוי בתקציב ודורש חשבונאות בשלה. סכימת חיוב היברידית מסירה את הסתירה הזו באמצעות רמה בסיסית ותעריף נפרד לחריגת צריכה.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| מנוי עם מכסות | עומס יציב, התקציב קבוע לתקופה | חריגת צריכה נחתכת במגבלה או דורשת אישור ידני |
| תשלום לפי צריכה | פיילוטים, ביקוש לא אחיד או עונתי | קפיצות בחשבון, קשה יותר לחיזוי עבור הלקוח |
| סכימת חיוב היברידית | מוצר עיקרי עם עומס בסיסי ועומס שיא | נדרשים ספים, מקדמים וסקאלת חריגה ברורה |
| חבילות יחידות בתשלום מראש | לקוחות עם מחזור אישורים איטי | יתרות דורשות חשבונאות, החזרים ותאריכי תפוגה |
| תמחור לפי עמדות עבודה | עבודה משותפת של צוות קטן | לא משקף את העומס האמיתי על התשתית |
לא משנה איזה מודל נבחר, האינווריאנטים זהים: אירועי צריכה נכתבים ליומן בלתי משתנה עם מפתח אידמפוטנטיות, אגרגטים מחושבים לפי תקופות סגורות, ואירועים מאוחרים מתקבלים בחלון סובלנות ונכנסים להתאמה של המחזור הבא.
כך החישוב נשאר תואם לצריכה בפועל, והמעבר לסכימה אחרת מצטמצם להגדרה מחדש של כללים, ולא לכתיבה מחדש של החשבונאות.
שלבי הטמעה: מביקורת מתאר ועד מסירה
את העבודה אנחנו מובילים ברצף: כל שלב הבא נשען על הארטיפקטים של הקודם, ולא על הסכמות בעל פה. זה מאפשר לעצור בכל שלב ולקבל מתאר עובד, ולא חצי מערכת.
- ביקורת ארכיטקטורה. מנתחים את הקוד הנוכחי, התשתית וזרימות הנתונים: היכן חיים המודלים, איך נשמרים ארטיפקטי האימון, אילו תלויות יהיה צורך להחליף. בפלט — מפת צווארי בקבוק וסדר העבודות.
- סכימת ריבוי דיירים. בוחרים מודל בידוד: מסד משותף עם הפרדה לפי מחרוזת מזהה דייר או סכימה נפרדת לכל לקוח. עבור בקשות כבדות ואנליטיקה קובעים את הפתרון ברמת PostgreSQL — מדיניות גישה לשורות מסירה את הסיכון לדליפה בין חשבונות.
- חיוב ומגבלות. קושרים תעריפים לאירועים מדידים: קריאות למודלים, נפח טוקנים, זמן אינפרנס. החשבונאות אידמפוטנטית — וובהוקים חוזרים מספק התשלומים לא מכפילים חיובים ולא חוסמים את החשבון.
- הגדרת סביבות. שלושה מתארים — פיתוח, קדם-ייצור, ייצור — עם אותה שיטת פריסה ומכסות שונות. התצורות מנוהלות בגרסאות, סודות לא נכנסים לתמונות.
- מתאר MLOps. מאוטמטים אימון ופריסה של מודלים, מוסיפים הקנרית לחלק מהתעבורה ומדדי איכות. הופיעה ירידה בביצועים — החזרה לגרסה הקודמת אורכת דקות.
- בדיקת עומס. מריצים תרחישים עם פרופיל בקשות אמיתי וכמה דיירים בו-זמנית: בודקים היכן נתקע התור, איך גדל השיהוי ואיך מתנהגות המגבלות בזמן זינוק.
- מסירה. מוסרים מאגרי קוד, סכימות, מדיניות והוראות תפעול, ומקיימים הדרכת צוות.
אחרי המסירה המתאר נשאר ניתן לניהול בלי מעורבות שלנו.
ערכה בפלט: תצורות, סכימות ותקנות
הערכה בפלט היא חלק עובד של הפלטפורמה, ולא נספח למסירת הפרויקט. לפיה מהנדסי הלקוח משחררים עדכונים, מחברים דיירים חדשים ומנתחים תקריות בלעדינו, ולכן כל ארטיפקט עונה על השאלה «איך לשחזר ולשנות», ולא «מה נעשה».
- תצורת סביבות — תבניות תשתית לפיתוח, קדם-ייצור וייצור: משתנים, מגבלות, חיבורים חיצוניים; מפתחות גישה הועברו לאחסון נפרד ואינם נמצאים במאגר הקוד.
- סכימת נתונים ותפקידים — מודל בידוד דיירים, מטריצת הרשאות ומיגרציות הפיכות: דייר חדש מוקם מתבנית בפעולה אחת, בלי עריכות ידניות במסד.
- תקנון שחרור עדכונים — סדר בנייה ובדיקות חובה, שחרור תחילה לחלק מהדיירים, קריטריונים ונוהל חזרה לאחור.
- חיוב — כללי תעריף, חשבונאות צריכה לפי דייר, התאמת חיובים וסדר טיפול בפערים.
- תצפית ואיכות מודלים — לוחות לפי שיהויים ושגיאות, ספי ירידה בביצועים, סדר אימון מחדש בלי לעצור את השירות.
- בקרת גישה וביקורת — תפקידים לתפעול ולתמיכה, יומן פעולות, החלפת מפתחות ושלילת הרשאות.
- תיעוד ומסירה — מפת שירותים, החלטות שהתקבלו עם סיבות, ניתוחי תקריות, הדרכת הצוות על משימות אמיתיות.
המסירה נחשבת לסגורה כאשר הלקוח בעצמו משחרר עדכון ומחבר דייר חדש. מכאן אנחנו נשארים בקשר לשינויים מורכבים, אבל הפלטפורמה חיה בלעדינו.
מקרה בוחן: ממתאר משותף אחד לבידוד לפי לקוחות
נקודת מוצא
פלטפורמת ריבוי דיירים החזיקה את כל הלקוחות במתאר Kubernetes אחד: תורי משימות משותפים, מסד אחד, קו בנייה אחד. השכנות יצרה אפקט «שכן רועש» — זינוק בעומס אצל לקוח אחד מתח את תגובות ה-API אצל האחרים, והיומן אסף אירועים של כל הדיירים לפיד אחד.
שחרור השינויים נעשה בחבילה אחת לשבועיים ותמיד בבת אחת לכולם, ולכן תיקון קטן של לקוח אחד חיכה לבדיקות של האחרים.
מה שינינו ומה קיבלנו
את הדיירים פיזרנו בין מרחבי שמות נפרדים עם מגבלות משאבים משלהם, תורים וסכימות נתונים, ואת הבנייה והשחרור הפרדנו לערוצים עצמאיים עם בקרת דייר בגבול: לפיה מנותבים בקשות, תמחור ויומנים.
| פרמטר | מתאר משותף | בידוד לפי לקוחות |
|---|---|---|
| שחרור שינויים | אחת לשבועיים, בחבילה | שניים-שלושה ימים, לפי לקוח |
| תקלות בגלל השפעת שכנים | כ-40% מהתקריות | מקרים בודדים |
| שחזור אחרי תקלה | 3-4 שעות, ידנית | 20-30 דקות, מתבנית |
| חיבור לקוח חדש | כשבועיים | יום-יומיים |
חלק התקלות שנגרמו מהשפעה הדדית בין לקוחות ירד למקרים בודדים: כעת ברוב התקריות הסיבה מקומית ונראית בגבולות דייר אחד. חזרה לגרסה קודמת הפכה לפעולה ברמת לקוח, ולא ברמת כל הפלטפורמה, ולכן שינויים יוצאים פי כמה יותר часто ועם פחות סיכון.
במה שונה ריבוי דיירים ממתאר נפרד?
ריבוי דיירים ומתאר נפרד הם שני קצוות של אותה הסתעפות, ולא «זול יותר ויקר יותר». במתאר משותף השירותים והמסד אחדים, והבידוד מושג לוגית: סכימות לדייר או כללי גישה ברמת שורות, מפתחות הצפנה משלהם, מכסות מחשוב. בגרסה נפרדת מעלים עבור לקוח סט שירותים משלו, אחסון משלו וקצב עדכונים משלו — הבידוד נעשה פיזי.
מתאר משותף מנצח במקום שבו חשובים שחרור אחיד ותחזוקה צפויה: בנייה אחת יוצאת לכל הלקוחות, טלמטריה ואימון מודלים נאספים בתור משותף, גרסה חדשה מופרסת מיד, ולא לעשרות אתרים. המחיר לכך הוא אזור כשל משותף: תקלה או אימון עתיר משאבים של לקוח אחד פוגעים בשכנים.
לכן הבידוד צריך להיות ניתן לבדיקה, ולא מוצהר: מדיניות ברמת שורות, מגבלות על משימות בו-זמניות, חשבונות נפרדים לאחסון.
מתאר נפרד ללקוח פותר משימות אחרות — דרישות מחמירות למיקום נתונים, אינטגרציות משלו, פרופיל שיאים לא סטנדרטי, צורך בגרסה קבועה. המחיר — מספר הישויות שצריך לעדכן, לבדוק ולשחזר באופן בלתי תלוי.
בלי אוטומציה של פריסה ותבניות חוזרות, אחרי כמה לקוחות התמיכה נתקעת בפעולות ידניות, והפריסה אורכת שעות במקום דקות.
סכימת פריסה היברידית מסירה את הקיצוניות: שכבת ניהול משותפת — גישות, חיוב, אנליטיקה, תזמור אימון — נשארת אחידה, ואילו הנתונים ומשאבי המחשוב חיים במתאר של הלקוח. שירותי הניהול מתעדכנים בפריסה אחת, נתונים רגישים ואימון כבד לא יוצאים מהאתר המבודד.
גבול הבחירה עובר בשלוש שאלות: מה דורש בידוד — נתונים, עומס או הגרסה עצמה; איזה פרופיל שיאים ואימון מודלים צפוי; כמה לקוחות ובאיזו תדירות הם משתנים. כל עוד הדרישות סטנדרטיות, מתאר משותף עם בידוד אמיתי זול יותר לתחזוקה.
ברגע שמופיע «נתונים רק אצלנו» — עוברים להיברידי, ומתאר נפרד לחלוטין נשאיר למקרים בודדים עם תנאים מיוחדים.
ספקות טכניים לגבי הפלטפורמה לפני תחילת העבודה
לפני תחילת העבודה הקבלן בדרך כלל שומע את אותן שלוש שאלות: איך להעביר פלטפורמה שכבר עובדת בלי לעצור את השירות, איך להפריד פיזית נתונים של לקוחות שונים, ומה יקרה למודלים כשהאיכות שלהם תתחיל לרדת. עונים לגופן — בלי הבטחות כלליות.
איך להעביר פלטפורמה קיימת בלי השבתה?
מקימים מתאר יעד לצד הנוכחי, מפעילים כתיבה כפולה ומעבירים נתונים במנות, תוך השוואת סכומי בקרה לפי טבלאות. מעבר התעבורה נעשה דרך דגל בתצורה, ולכן החזרה למתאר הקודם אורכת דקות, ולא שעות.
איך מוגנים נתוני הלקוחות ברמת הפלטפורמה?
הבידוד נבנה בשתי רמות: סכימת אחסון נפרדת וסימן חובה של הלקוח בכל שאילתת נתונים, שאותו בודק שכבת הגישה, ולא קוד המסכים. מפתחות הצפנה מונפקים לכל לקוח בנפרד, ולכן הגישה נשללת נקודתית, בלי לעצור את שאר הדיירים.
מי מתחזק את המודלים אחרי ההשקה?
אחרי המסירה פועלים ניטור איכות על מדגם נפרד ומרשם גרסאות של המודל: ירידת דיוק נראית לפני שמגיעות תלונות. אימון מחדש מתבצע לפי לוח זמנים ולפי סימן להסטת נתונים, והחזרה לגרסה הקודמת — בפעולה אחת. העברת הידע לצוות הלקוח נעשית יחד עם התיעוד וניתוח התקריות.
נדון במשימה ונחזור עם הערכה ותוכנית
ניתוח הארכיטקטורה הראשון הוא לא היכרות, אלא פגישת עבודה עם המהנדסים שיובילו את הפרויקט. אנחנו מנתחים את המצב הנוכחי והמגבלות, כדי לחזור עם הערכה ותוכנית עבודה, ולא עם מילים כלליות על לוחות זמנים.
מה מבררים כדי שההערכה תהיה מציאותית:
- גבולות ריבוי הדיירים: מסד משותף עם סכימות לדייר, מסדים נפרדים או מתארים נפרדים — והיכן בדיוק עובר גבול הנתונים של לקוחות הפלטפורמה.
- מודל תעריף: מה נלקח כיחידה — פנייה, נפח נתונים מעובדים או משתמש פעיל; איך מחשבים מגבלות ומה קורה בחריגה מהן.
- מחזור חיים של מודלים: היכן נשמרים ארטיפקטים ונתוני אימון, איך מפרסים גרסה חדשה וחוזרים לקודמת בלי השבתה.
- מה כבר קיים בתשתית: ענן או שרתים משלנו, תור משימות, אחסון, ניטור והתראות.
- נתונים וגישות: נתונים אישיים, תיעוד יומנים, תקופות שמירה, מי בתוך הפלטפורמה רואה נתונים של דייר.
- פרופיל עומס: כמה דיירים ופניות צפויים, איזה זמן תגובה נחשב סביר ומה עושים בשיא.
זו שיחה עניינית: כדי לדון במשימה לגופו של עניין, די לתאר את המוצר, את הדיירים ואת מה שכבר מוכן. בסיומה תקבלו תוכנית עבודה לפי שלבים עם גבולות אחריות וסדר מסירת תיעוד — סכימות, תצורות, הוראות תפעול, כדי שהפלטפורמה תישאר ניתנת לניהול גם בלעדינו.







