Azure Cosmos DB: היכן תצורת ברירת המחדל אינה מחזיקה בעומס
Azure Cosmos DB סולחת על הרבה בסביבת בדיקות עם מפתח אחד, וכמעט מיד מתחילה להפריע בפרודקשן.
תצורת ברירת המחדל מניחה שתבחרו במודע מפתח מחיצה, ותקצו קיבולת לפרופיל השאילתות האמיתי — אם לא עושים זאת, הדבר הראשון שמופיע הוא מחיצה חמה: קבוצה לוגית אחת מקבלת כמות לא פרופורציונלית של פעולות, והשאילתות אליה מתחילות להחזיר סירובים בגלל מחסור בתפוקה, אף שלכאורה יש מלאי כללי.
לרוב הטעות במפתח המחיצה מקורה במודל הנתונים, לא בתצורה. אם נבחר שדה בעל קרדינליות נמוכה או שדה שלפיו מתבצע סינון בדוחות, השאילתה הופכת לחוצת-מחיצות: היא פונה לכל המחיצות, אוכלת יחידות בקשה בקבוצות, וזמן הריצה שלה גדל יחד עם נפח האוסף.
הסימפטומים מוכרים — השהיה לא יציבה של שאילתות בשיאים, פיזור ניכר בין קריאות מהירות לאיטיות, ו"מסור" בצריכת הקיבולת, שבגללו צריך להחזיק מלאי גבוה מהחישוב.
סיפור נפרד — עריכות ידניות בקונסולה: אינדקסים, רמות עקביות, מדיניות TTL ופרופילי התרחבות, שהוגדרו "בזריזות" במהלך תקרית. זה עובד, אבל הסביבה מפסיקה להיות משוחזרת: בדיקות ופרודקשן מתפצלים, פריסה של עותק חדש לא נותנת את ההתנהגות המצופה, והתיקון הבא שוב נעשה ביד.
מגבלות הקיבולת לא נרפאות בהעלאת התקרה: בלי נרמול של מפתח המחיצה והאינדקסים, לא התפוקה גדלה, אלא החשבון עבור כל פעולה.
בהמשך נפרט איך זה נסגר — מבחירת המפתח ומודל הקיבולת ועד תיאור התצורה כקוד, כך שהסביבות ייבנו באופן זהה.
מה נותנת תצורת אחסון מדויקת
תצורה מדויקת של Azure Cosmos DB אינה הפעלה חד-פעמית, אלא סט פרמטרים שכל אחד מהם נראה במטריקות: מפתח מחיצה, מדיניות אינדוקס, רמת עקביות, מלאי תפוקה. השילוב ביניהם קובע כמה פעולות עוברות ללא ניסיונות חוזרים וכמה מהר חוזרת התשובה.
הפחתת שיעור הסירובים בעת קפיצות שיא
קפיצת שיא לא שוברת את האחסון, אלא את פיזור העומס: מפתח מחיצה חם אחד אוסף את רוב הכתיבה ומתחיל להחזיר סירוב בגלל חריגה מהתפוקה.
אנחנו מאזנים את המפתח לפי דפוסי הגישה בפועל, מוסיפים מלאי והתרחבות אוטומטית לפרופיל היומי — שיעור הסירובים בשיאים יורד לעשיריות האחוז, ומפולת ניסיונות חוזרים לא מתחילה.
תגובה צפויה לקריאה ולכתיבה
השהיית קריאה נוצרת לא מהרשת, אלא מסריקה: שאילתה בלי מפתח מחיצה עוברת על מסמכים מיותרים, וזמן התגובה גדל יחד עם נפח הנתונים. קריאה ממוקדת לפי מפתח ואינדקסים מכסים עבור מסננים מסוימים הופכים את התגובה ליציבה.
אינדוקס וצריכת קיבולת קשורים ישירות: מדיניות על הנתיבים הנדרשים במקום "לאנדקס הכול" מפחיתה את עלות הכתיבה, והמשאב שהתפנה עובר לעומס המועיל.
מה אנחנו מתעדים בדוח לפי התוצאות:
- שיעור הסירובים בשיאים ובשעות שפל;
- זמן תגובה של קריאה וכתיבה לפי דפוסי השאילתות המרכזיים;
- שיעור הפעולות שעברו ללא ניסיונות חוזרים;
- פיזור התגובה בין שעות העבודה לשיא.
מצבי עקביות ומודלי קיבולת
מצב עקביות ומודל קיבולת ב-Azure Cosmos DB נבחרים יחד עם מפתח המחיצה: מהמפתח תלוי השרדינג, וממנו — איך תתנהג ההתרחבות האוטומטית בשיאים. להחליף את ההחלטות האלה אחרי ההפעלה עולה יותר זמן מאשר לדון בהן בהתחלה.
עקביות: מה מפסידים ומה מרוויחים
ככל שמצב העקביות מחמיר יותר, כך עולים השהיית הקריאה והעומס על השכפול, אבל האפליקציה לא רואה נתונים מיושנים. את הרמה מתאימים לפעולה: חישובים צריכים קריאה מחמירה, בעוד פידים ומונים חיים על עקביות סשן או סופית.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| מחמירה | חישובים שבהם פער אינו מתקבל על הדעת | השהיית הקריאה הגדולה ביותר |
| התיישנות מוגבלת | פיגור קריאה בחלון מוגדר מתקבל | החלון נשלט על ידי האפליקציה |
| סשן | קריאה של הכתיבות של עצמך | הסדר בין סשנים אינו מובטח |
| קיבולת מוקצית | זרימה יציבה וצפויה | המלאי לא מתפנה מעצמו, קנה המידה ידני |
| קיבולת אלסטית | עומס פועם ושיאים | ההתרחבות מגיבה בהשהיה |
קיבולת מוקצית מול אלסטית
קיבולת מוקצית מחזיקה מלאי קבוע ומתאימה לשירותים עם תעבורה יציבה; אלסטית מתכווננת בעצמה, אבל התגובה לשיא מגיעה בהשהיה. אנחנו מחשבים פרופיל עומס לפי שאילתות אמיתיות ובוחרים מפתח מחיצה כך שהשרדינג יפזר את הנתונים באופן שווה ולא ייווצרו מחיצות חמות.
איך אנחנו מנהלים עבודה ב-Azure: מביקורת ועד מסירה
בתחילה אנחנו מתעדים את רשימת הקונטיינרים, מפתחות המחיצה הנוכחיים ופרופיל העומסים: איך גדלים הנתונים, היכן שאילתות קוראות מכמה מחיצות, ואילו שיאי צריכה חלים בשעות הדיווח. במקביל אנחנו מתעדים דרישות — חלון אי-זמינות מותר, עומק שחזור, ומי הבעלים של התשתית לאחר המסירה.
מה אנחנו מבררים בתחילה
צריך את אותם נתוני פתיחה שגם לצוות שלכם: מפת השאילתות ותדירויותיהן, נפח וקצב גידול הנתונים, מגבלות עקביות, דרך הפריסה הרגילה ונוהל הגישה לסודות. בלי זה סכימת המחיצות מתוכננת באקראי.
- ביקורת סכימת המחיצות. מנתחים מפתחות מחיצה, אינדקסים ופרופיל שאילתות: היכן קריאה עוברת בכל המחיצות, ואילו מהן נתקלות בתקרה בשיא. בפלט — מפת צווארי בקבוק והכרעה לגבי הפריסה.
- תכנון החלוקה ומצב העקביות. מתאימים מפתח לשאילתות אמיתיות, בודקים גידול מחיצות ובוחרים רמת עקביות — היא משפיעה על ההשהיה ועל הפערים המותרים בין עותקים.
- תשתית כקוד. קונטיינרים, תפוקה, אינדקסים ותפקידי גישה מתארים באופן הצהרתי: התצורה חיה במאגר, עוברת בדיקה ונפרסת בסביבות אחדות באופן זהה.
- הגדרת Cosmos DB דרך Terraform והגירה ללא השבתה. מרימים פריסה חדשה לצד הפעילה, מעבירים תעבורה בשלבים ומעבירים נתונים תוך בקרת פיגור. חלון אי-הזמינות — אפס, והנסיגה לסכימה הקודמת נשארת מוכנה.
- בדיקה על פרופיל עומס. מריצים תרחיש שיא ותרחיש ממושך, בודקים התנהגות בזמן גידול מחיצות, מגדירים התראות וחוקי התרחבות. נוהל הגיבוי מתעדים בכתב ובודקים שחזור.
- מסירה והדרכת הצוות. מוסרים מאגר, סכימת סביבות, מדיניות גישה וסדר שינויים, ומקיימים סקירה עם המהנדסים — התמיכה ממשיכה בלעדינו.
מה נשאר לכם אחרי ההטמעה: תצורות ונהלים
את התשתית אנחנו לא משאירים "קופסה שחורה": יחד עם אשכול פעיל אתם מקבלים ארטיפקטים שלפיהם אפשר לפתח ולתפעל אותה בכוחות עצמכם. התיאור נשמר במאגר שלכם תחת בקרת גרסאות — שינויים עוברים סקירה, ולא עריכות ידניות בקונסולה.
הרכב התיעוד הנמסר
- תצורה כקוד. מודולים לתיאור בסיסי Cosmos DB, חשבונות, רמת עקביות ומדיניות גיבוי, עם סט משתנים נפרד לסביבת בדיקות ולסביבת ייצור.
- סכימות חלוקה ואינדקסים. מפת מפתחות מחיצה עם נימוק הבחירה, מדיניות אינדוקס לפי קונטיינרים וחישוב תפוקה לפרופיל העומס.
- מדיניות גישה ותפקידים. מטריצת "מי ומה יכול", קישור הרשאות לחשבונות שירות ולזהויות מנוהלות, ועיקרון ההרשאה המינימלית הנדרשת.
- סכימות ודיאגרמות. טופולוגיית הפריסה, שכפול בין אזורים, רשימת נקודות כשל וסדר העברת התעבורה.
- נוהל גיבוי. תדירות צילומים, תקופות שמירה ותרחיש שחזור שלב אחר שלב עם בדיקת שלמות הנתונים.
- הוראות לתקריות. כשלים אופייניים — מיצוי תפוקה, סירוב חלק מהשאילתות, גידול בהשהיות: מה לבדוק ואיזה פרמטר לשנות.
- נהלי תפעול. סדר הוצאת שינויים, חלונות תחזוקה, בקרת עלות השאילתות וחוקים להוספת קונטיינרים חדשים.
כל מסמך קשור למצב בפועל של הסביבה ומתעדכן יחד איתה: נוהל שמנותק מהקוד מתרחק מהמציאות במהירות.
מקרה בוחן: בנייה מחדש של סכימת המחיצות לעומס שיא
שירות רב-דיירים: הזמנות, מחסן, דוחות. הקונטיינרים ב-Azure Cosmos DB גדלו יחד עם מספר הלקוחות, ובשיאים עונתיים השאילתות החלו ליפול. לא ניתחנו את העומס, אלא את סכימת המחיצות: היא תוכננה פעם לזרימה יציבה, לא לשיא.
מה היה לפני
מפתח המחיצה היה מזהה הלקוח. אצל דיירים גדולים הצטברו במחיצה עשרות מיליוני מסמכים, ואצל האחרים המחיצות עמדו ללא שימוש — חלק מהמחיצות הפיזיות עבדו על הקצה.
ייצוא המוני עבור לקוח גדול העלה את הצריכה עד התקרה, והבסיס החזיר סירובים בגלל חריגה מהמגבלה: בשיא שיעור השאילתות הכושלות הגיע לכמה אחוזים. בעיה נפרדת — כל השדות אונדקסו ברצף, וכל כתיבה גררה בנייה מחדש של האינדקס.
מה קרה אחרי
עברנו למפתח מורכב: דייר בתוספת חלון זמן — חודש עבור מסמכים תפעוליים, שנה עבור ארכיון. לקוחות שהחלון שלהם נשאר חם פוזרו באמצעות סיומת סינתטית של שמונה מקטעים מההאש של המזהה.
הדוחות הועברו לקונטיינר נפרד עם מפתח משלו, האינדוקס צומצם לשדות של מסננים אמיתיים, ובהיסטוריית הארכיון הופעל TTL למסמך.
שיעור הסירובים בגלל מגבלות בשיא ירד מכמה אחוזים לעשיריות האחוז, זמן התגובה לשאילתות כבדות התקצר פי כמה, והפיזור בעומס בין מחיצות חמות לקרות — בתוך סדר גודל אחד במקום שניים. הנתונים גדלו פי שלושה באותה תפוקה.
נעלם סוג הכשל שבו דייר אחד אכל את המחיצה והפיל את התגובה לכולם. הסכימה ניתנת להעברה לכל מודל רב-דיירים: מפתח המחיצה נבחר לפי תמונת הגישה, לא לפי מבנה הישויות.
מה לעשות אם בסיס הנתונים כבר פרוס והעומס גדל?
אפשר לבנות מחדש סכימת מחיצות על נתונים חיים — אבל לא "במקום". מפתח המחיצה קובע את המיקום הפיזי של המסמכים, ולכן בקונטיינר קיים הוא לא משתנה: מרימים קונטיינר חדש ומעבירים אליו נתונים, בעוד בסיס Cosmos DB שכבר פרוס ממשיך לשרת תעבורה. זה עובר בלי עצירת השירות, אם האפליקציה יודעת לעבוד עם שני מפתחות בו-זמנית.
הסדר הוא כזה: מתעדים פרופיל עומס ופיזור נתונים לפי המפתח הנוכחי, בוחרים מפתח חדש לפי קרדינליות ואחידות, ומפעילים כתיבה כפולה לקונטיינר היעד. אחר כך העברה ברקע עם בדיקת סכומי ביקורת לפי מחיצות לוגיות, העברה הדרגתית של קוראים, ורק לאחר השוואה — ניתוק המעגל הישן.
תאימות לאחור של האפליקציה נבנית מראש: שכבת הגישה קוראת לפי שני המפתחות וכותבת לחדש, ולכן הנסיגה אורכת דקות ולא שעות. מעבר בין מודלי קיבולת לא עובר כך בצורה חלקה — החלפת המצב נוגעת ברמת החשבון, ולכן מתכננים חלון תמיכה קצר עם חימום ובדיקת תרחישים מרכזיים מיד לאחריו.
מה נותנת בנייה מחדש של סכימת המחיצות: שאילתות חוצות-מחיצות מפסיקות לאכול את התפוקה המשותפת, המחיצות הלוגיות העמוסות ביותר לא נתקלות יותר בתקרה, וגידול הנתונים שוב מתפזר באופן שווה. מתחילים ממדידות, לא מהעברה — אז ההחלטה נשענת על פרופיל העומס, לא על ניחושים.
נקודות מחלוקת: עקביות, אינדקסים, גישה
כמעט כל החלטה לגבי Cosmos DB היא פשרה בין השהיה, זמינות וצריכת יחידות בקשה. בסקירה לפני ההפעלה עולים אותם ספקות — להלן תשובות קצרות לאלה שלרוב מעכבות את האישור.
כמה מחמירה צריכה להיות העקביות?
מחמירה נותנת פעולות ליניאריות, אבל מצמידה את הקריאה לאזור הכתיבה: ההשהיה גדלה והזמינות יורדת בעת אובדן אזור. רמת סשן מכסה את רוב התרחישים — הלקוח קורא את הכתיבות של עצמו. אנחנו מחזיקים אותה כברירת מחדל, ומפעילים מחמירה נקודתית.
האם לאנדקס את כל השדות זה תקין?
לא: כל נתיב מיותר מוסיף צריכת יחידות בקשה לכתיבה ומנפח את האחסון. אנחנו מוציאים שדות בלי מסננים ומיון, משאירים אינדקסים מורכבים עבור דפוסי שאילתות מסוימים, ומשווים את המדיניות ליומן השאילתות לפני העלייה לפרודקשן.
אפשר להסתדר בלי מפתח ראשי באפליקציה?
כן, דרך זהויות מנוהלות ותפקידים — מובנים או מותאמים אישית, עם היקף לחשבון, לבסיס נתונים או לאוסף. המפתח נשאר במאגר סודות רק לצורך הגירות ומסתובב לפי לוח זמנים.
מה נותן הגיבוי ואיך משחזרים?
עותקים תקופתיים עם חלון שמירה או מצב רציף. השחזור מתבצע לא מעל הנתונים הקיימים, אלא לחשבון חדש: מחרוזת החיבור והגישות מוגדרות מחדש, ולכן מתרגלים את המעבר מראש.
מי אוכל את תקציב עיבוד השאילתות?
לרוב לא המקור, אלא מקטעי מחיצה "חמים": כשמפתח החלוקה מוטה, כמעט כל הזרימה הולכת לחלק אחד. בודקים מטריקות לפי מקטעים, מנתחים שאילתות כבדות ומפזרים מחדש את המפתח או מוציאים את הקריאה למודל נפרד.
נדון במשימה ונחזור עם תוכנית עבודה
כדי שאומדן העבודה יישען על עובדות ולא על הנחות, נאסוף סט נתוני פתיחה. להלן מה לשלוח לפני השיחה; כאשר הגישה לפרודקשן מוגבלת, חלק מהסעיפים מוחלפים בייצוא אנונימי.
- סכימת נתונים: קונטיינרים, מפתחות מחיצה, אינדקסים נוכחיים ו-TTL, מודל עקביות, נפחים וקצב גידול של אוספים.
- פרופיל עומס: שאילתות בשנייה ויחס קריאה-כתיבה, גודל מסמך, חלונות שיא, גיאוגרפיה של לקוחות ופיזור לפי אזורים.
- תצורות נוכחיות: מצב תפוקה, רמות עקביות, מדיניות אינדוקס, הגדרות גיבוי, תיאורי תשתית ומצב, אם המשאבים כבר מנוהלים ב-Terraform.
- גישות לביקורת: קריאה במנוי, מטריקות, יומני אבחון ולוגים של שאילתות איטיות; ייצוא אנונימי מספיק.
- דרישות ומגבלות: זמן שחזור יעד ונקודת אובדן נתונים מותרת, דרישות רגולטוריות, חלונות תחזוקה, סדר אישור שינויים.
- קריטריוני מוכנות: השהיה באחוזון 95, שיעור שאילתות בלי הגבלת תפוקה, צפיות גידול האחסון.
בשיחה ננתח את הנתונים האלה ונחזור עם אומדן עבודה, תוכנית הטמעה בשלבים עם נקודות נסיגה, סדר מסירת תיעוד ואפשרויות תמיכה לאחר ההפעלה.







