מה נשבר בלי cross-region replication
תקלה באזור המקור לעתים רחוקות נראית כמו "האזור נעלם כולו". לעתים קרובות יותר קטע מסוים אינו זמין: ה-bucket מחזיר שגיאות קריאה, גדל שיעור הבקשות שלא עומדות בזמן שהוקצב, וה-load balancer מוציא בהדרגה את הצומת מהסבב.
השירות פורמלית חי, אבל כל פעולה שזקוקה לאובייקט לפי מפתח נכנסת לתור — ההידרדרות מתפשטת להעלאת קבצים, ייצוא דוחות ועיבוד תורים.
המחצית השנייה של הבעיה — איכות העותקים באזור הגיבוי. Cross-region replication מופעל, אבל השהיה בין כתיבה להופעת האובייקט באזור אחר נמדדת בשעות, חלק מה-buckets נוספו מאוחר יותר ולא נכנסו לכללים, ומחזורי חיים העבירו חומר שלא שוכפל לארכיון קר.
ברגע המעבר מתברר: חלק מהאובייקטים חסרים כליל, אחרים — עותק מיושן של אובייקטים, ואי אפשר להבדיל ביניהם לפי מטא-נתונים. כשל של אזור האחסון חושף את העובדה שהשכפול הוגדר לצורכי דיווח, לא לצורכי שחזור.
המחיר של תקלה כזו — לא זמן השבתה, אלא זמן שחזור השירות: בזמן שגופי האובייקטים עולים מהארכיון, האפליקציה עובדת במצב קריאה בלבד או מחזירה נתונים חלקיים.
אובדן נתונים בתקלה מפסיק להיות תיאוריה — אישורי כתיבה קיימים, אבל האובייקטים עצמם נשארו באזור אחד, ואחרי החזרה יש לטפל ידנית בפערים בין העותקים. הנה כיצד זה נסגר.
מה נותן אחסון אובייקטים עמיד לתקלות
אחסון אובייקטים עמיד לתקלות נבנה לא על עותקים נדירים "ליתר ביטחון", אלא על סנכרון קבוע בין אזורים: הכתיבה מאושרת באזור הראשי, והעותק שלה מגיע לאזור הגיבוי. ניתוק ערוץ או תקלה באתר מפסיקים לאומר אובדן נתונים — באזור הגיבוי נמצא תצלום עדכני של האחסון, מוכן למסירה.
מעבר לאזור הגיבוי בתרחיש מתורגל אורך עשרות דקות במקום שעות של שחזור מעותקים לא מקוונים. תעבורת הקריאה מועברת על ידי שינוי כתובת נקודת הכניסה, וקישורים חתומים ומדיניות גישה ממשיכים לעבוד, כי הכללים והמפתחות משוכפלים יחד עם התוכן.
שיעור הבקשות שהאחסון משרת ללא התערבות ידנית באותו רגע נשאר ברמת עומס רגיל — הולכות לאיבוד רק פעולות כתיבה בחלון הפיגור של הרפליקה.
את שלמות האובייקטים מבטיחה לא עצם ההעתקה, אלא בדיקה: סכומי ביקורת נבדקים לאחר ההעברה, גרסאות שומרות על מהדורות קודמות, וכללי מחזור חיים לא נותנים לרפליקה לפגר ללא סוף בזרימה גדולה.
זה עקרוני, כי אובייקט פגום בשקט מסוכן יותר מאובייקט חסר — האפליקציה קוראת אותו כתקף ומחזירה אותו למשתמש.
האפקט המרכזי — משתנה מחלקת הכשלים שמפסיקה להיות קריטית. כשל של אזור, אזור זמינות או קו תקשורת ראשי בין אתרים כבר לא עוצר את השירות: המעבר מתבצע לפי תוכנית, לא במצב חירום.
הזמינות של אחסון האובייקטים בסכימה כזו נקבעת לא לפי השאלה אם האזור הראשי חי, אלא לפי המהירות שבה אתם מוכנים להחליף נקודת כניסה.
אפשרויות סנכרון בין אזורים
סנכרון אסינכרוני — מצב בסיסי: האובייקט נרשם באזור המקור, נכנס לתור ההעברה ומופיע ביעד תוך שניות או דקות. הכתיבה אינה תלויה בזמינות האתר השני, הערוץ לא חוסם מסירת נתונים, ולכן כך מעבירים את עיקר הנתונים. המחיר הוא חלון שבו העותק עדיין לא קיים.
כתיבה סינכרונית לשני אזורים מחזירה אישור רק לאחר רישום האובייקט בשני האתרים. העותק קיים ברגע התשובה, אבל כל בקשה ממתינה לאזור השני, ואי-זמינות שלו עוצרת את הכתיבה. לכן המצב נלקח עבור סט צר של קידומות קריטיות, ולא עבור כל ה-container.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| סנכרון אסינכרוני | עיקר נפח הנתונים, אובייקטים גדולים, פיגור מותר של העותק | העותק מופיע בהשהיה; בכשל של המקור ייתכן אובדן של הכתיבות האחרונות |
| כתיבה סינכרונית לשני אזורים | קידומות קריטיות שבהן העותק נדרש ברגע הכתיבה | זמן התגובה גדל, כשל של אזור היעד חוסם פעולות |
| שרשרת אזורים | אספקה גיאו-מבוזרת, כאשר העברה ישירה יקרה יותר בערוץ | ההשהיה מצטברת לכל חוליה, ניתוק של צומת אמצעית עוצר את כל הזרימה, האבחון מסובך יותר |
| סנכרון סלקטיבי של קידומות | חלק מהנתונים לא צריך לצאת מהאזור | יש לתחזק כל כלל חדש — קידומת שהוחמצה נשארת בלי עותק |
בנפרד יש להתחשב בכללי מחזור החיים של אובייקטים: הם לא עוברים בירושה לאזור היעד באופן אוטומטי. אם לא מגדירים מדיניות בנפרד, העותקים או מצטברים, או נמחקים לפני המקור — וחזרה למצב קודם נעשית בלתי אפשרית.
סדר היישום: מביקורת ועד מסירה
מתחילים בסקירה, לא בהפעלת כללים. לרוב ה-buckets כבר יש גרסאות, מדיניות מחזור חיים וזרימות כתיבה משלהם — שכפול מעליהם עובד רק כאשר זה נלקח בחשבון מראש, אחרת מקבלים כפילויות ופערי גרסאות.
-
ביקורת אחסון האובייקטים. מלאי של buckets וקידומות: נפח, פרופיל גישה, האם גרסאות מופעלות, אילו כללי מחזור חיים כבר פועלים, מי ואיך קורא את הנתונים.
-
סכימת זרימות נתונים. קובעים מה ולאן משוכפל: קידומות, כיוון, האם נדרש סנכרון חוזר, מה נכנס לחריגים — לוגים, ייצוא זמני, מטמון.
-
תכנון כללים. אזור יעד, תפקיד שכפול והרשאותיו, התנהגות בעת התנגשות גרסאות ובעת מחיקת אובייקט, מה לעשות עם הנפח שכבר נצבר.
-
הגדרת כללי סנכרון. פורסים כללים לפי buckets, מפעילים גרסאות במקור וביעד, מגבילים את תפקיד השכפול רק לקידומות הנדרשות.
-
בדיקת שלמות. משווים אובייקטים לפי סכומי ביקורת, עוקבים אחר פיגור השכפול והסטטוס בכל כלל, מריצים בנפרד כתיבה מחדש ומחיקה — בהם הפערים צצים לרוב.
-
ניטור. מדדים לכל כלל, התראות על עצירת שכפול ועל גידול בפיגור — אחרת התקלה תתגלה בניסיון קריאה מהאזור הגיבוי.
-
מסירה לתפעול. מתעדים את הסכימה, התפקידים ונוהל החזרה לאחור, מאמנים את המשמרת התורנית, מקבעים אחראים לשינויי כללים.
קונפיגורציות, מדיניויות ונוהלים בפלט
לאחר היישום נשאר לצוות לא "הגדרה בצד שלנו", אלא סט מלא של ארטיפקטים שלפיהם אפשר לתפעל ולפתח את האחסון בלעדינו. כל סעיף נבדק בסביבת בדיקות ומקושר לפעולה קונקרטית: מה לערוך כשמוסיפים bucket, לאן להסתכל כשהשכפול בין-אזורי מפגר ולמי להסלים בלילה.
- קונפיגורציות של כללי שכפול — מניפסטים במאגר, לא הגדרות ידניות בקונסולה: סינון לפי קידומות ותגים, חריגים לאובייקטים זמניים, היסטוריית שינויים.
- מדיניויות גישה ל-buckets — הפרדה בין הרשאות קריאה וכתיבה לפי תפקידים, גישה ציבורית סגורה, גרסאות חובה, הגבלת גישה לנקודות כניסה שירותיות.
- תפקידים והרשאות לשכפול — תפקיד שירות נפרד עם סט מינימלי: קריאת אובייקטים ותגים במקור, כתיבה ל-bucket היעד, סדר הקצאה ושלילה.
- סכימת זרימות נתונים — מקור, אזור יעד, כיוון ההעתקה, מצבי אובייקטים בדרך והנקודה שבה העותק הופך למקור הראשי בעת תקלה.
- נוהל תחזוקת האחסון — תדירות בדיקת שלמות העותק, סדר החלפת אזור היעד, מחיקת גרסאות מיושנות, ספי מדדים והתראות לתורן.
- הוראות למשמרת התורנית — שלב אחר שלב: בדיקת מצב, העברת עומס לעותק, עצירה וחידוש שכפול, הסלמה; עם סימון אילו פקודות בטוחות ואילו דורשות אישור.
איך הסרנו את התלות באזור אחד
הלקוח — שירות מוצרי עם קהל בשני יבשות, אחסון האובייקטים ישב באזור אחד, תואם S3. שם גם נשמרו נתונים חמים וגם גיבויים, ולכן תקלה באתר עצרה את השירות כולו, והשחזור מהארכיון ארך שעות ונתקע בקריאת הגיבויים.
הטמענו שכפול בין אזורים: כלל ברמת ה-container מעתיק כל אובייקט חדש או שהשתנה לאתר השני, גרסאות מופעלות שומרות על מהדורות קודמות, ומדיניות מחזור חיים לא נותנת לשני האתרים לגדול ללא גבול.
תחת השכפול נכנסו 46 מיליון אובייקטים; הפיגור של העותק אחרי המקור נשמר בטווח של דקות ספורות, וזה התקבל כמצב עבודה.
מה הראו התרגילים לניתוק
את האזור הראשי כיבו פעמיים במסגרת תרגילים מתוכננים: תעבורה הועברה לעותק, האפליקציה הועלתה באתר השני, קראו וכתבו אובייקטים בכתובות חדשות. זמן המעבר הצטמצם מארבעים דקות לשש, וצוואר הבקבוק התברר לא כנתונים אלא כשלבים ידניים בפריסת השירות — אותם העבירו לתרחיש אוטומטי.
גם המעבר חזרה נבדק: לאחר החזרת העומס האזור הראשי מדביק את השינויים מהעותק, ולא נותרים פערים בסכומי ביקורת. כעת תקלה באתר היא לא אובדן נתונים, אלא הפסקה לזמן המעבר.
במה cross-region replication שונה מגיבוי
Cross-region replication וגיבוי פותרים משימות שונות, אף ששניהם שומרים נתונים מחוץ לאזור הראשי. שכפול מחזיק עותק קבוע: אובייקט חדש מופיע באזור השני כמעט מיד לאחר הכתיבה, אפשר לקרוא ממנו, ובכשל של האזור — להעביר תעבורה. גיבוי הוא נקודת חזרה: תצלומים לזמנים מוגדרים, שמהם משחזרים מצב לתאריך הרצוי.
שכפול עוקב אחרי שינויים, כולל מחיקה: מחקתם אובייקט או כתבתם אותו מחדש — העותק יחזור על כך. הנתונים באזור השני תמיד עדכניים, אבל טעות לוגית משוכפלת באותה מהירות כמו כתיבה מועילה.
גיבוי בנוי אחרת: עותקים נוצרים לפי לוח זמנים או לפי אירוע, נשמרים בנפרד, עם הרשאות גישה משל עצמם ואחסון בלתי ניתן לשינוי. דווקא זה נותן הגנה מפני טעויות לוגיות — מחיקה המונית, פגיעה בנתונים, כשל באפליקציה או פעולות של כופר-תוכנה: נשאר מצב מלפני האירוע.
מכאן מדדים שונים. בשכפול אובדן נתונים נמדד בשניות, אבל הוא לא יעזור לחזור ליום אתמול. בגיבוי נקודת החזרה נבחרת במודע, אבל השחזור ארוך יותר: צריך לפרוס את הנתונים ולהעביר עומס.
בפועל אלה לא חלופות, אלא שתי שכבות הגנה. שכפול מכסה כשל של אזור ומאיץ גישה, גיבוי — טעויות בנתונים ודרישות לאחסון מצבים היסטוריים. הבחירה מתחילה בשאלה: צריך להעלות קו פעיל או להחזיר נתונים לנקודה מסוימת.
ספקות טכניים לפני הפעלה
הכלל תופס רק אובייקטים חדשים או שהשתנו — מערך שהיה קיים לפני ההפעלה לא יעבור מעצמו לשום מקום. לכן את ההפעלה מחלקים לשני שלבים: מפעילים את הכלל ובמעבר נפרד מעבירים את המצטבר, תוך השוואת התוצאה לפי רשימות וסכומי ביקורת.
להלן מה שמהנדסי הלקוח מבררים לפני ההפעלה הראשונה: גורל הנתונים הקיימים, בדיקת שלמות והתנהגות המערכת כאשר אזור היעד אינו זמין.
מה יקרה לאובייקטים הישנים בעת ההפעלה?
הכלל לא חל עליהם: את המערך המצטבר מעבירים במעבר נפרד לפי קידומות, במנות, עם דוח לכל אחת. ב-bucket עם גרסאות מושכים גם גרסאות קודמות וגם סמני מחיקה — אחרת באזור היעד יצופו קבצים "שחזרו לתחייה".
איך נבדקת השלמות לאחר ההעברה?
משווים גודל וסכומי ביקורת, קוראים באופן מדגמי אובייקטים מאזור היעד. פערים נכנסים לדוח, ומעבירים שוב רק אותם — אין צורך במעבר מלא מחדש.
מה אם אזור היעד אינו זמין?
אירועים נצברים בתור, והניסיונות החוזרים מתבצעים בהשהיה גדלה. הכתיבות נשארות במקור וזמינות, הפיגור נראה במספר הרפליקות שלא הושלמו; לאחר השחזור התור מתפנה מעצמו.
אפשר לסנכרן באופן סלקטיבי?
כן: הכלל מצומצם לפי קידומת, תגים וגודל. קבצים זמניים, מטמון ולוגים מוחרגים מיד, כדי שהעותק לא יתנפח מנתוני שירות.
האם נדרש סנכרון חוזר?
כלל דו-כיווני יוצר מחזור, ולכן כיוון הפוך מפעילים רק בזמן העברת תעבורה ומגנים עליו בגרסאות ובהפרדת קידומות. אחרת האובייקט ינוע ללא סוף בין האזורים.
נדון במשימת סנכרון האזורים
כדי להעריך את נפח השכפול לגופו של עניין, ולא "לפי תחושה", נדרשים לנו נתוני פתיחה על התשתית — חלק נברר בעצמנו, אבל חלק יודעים רק אתם. להלן רשימה של מה שכדאי להחזיק בהישג יד לשיחה.
- רשימת buckets וייעוד הנתונים: מה קריטי ומה משוחזר מהמקור.
- נפח ואופי הגדילה: מספר אובייקטים, גודל ממוצע, שיעור קבצים קטנים.
- אזורי יעד ודרישות להשהיית גישה לעותק מכל אחד מהם.
- סכימת הרשאות: תפקידים ומדיניויות בשני האזורים, האם יש קו נפרד לשכפול.
- כללי מחזור חיים: מה לשמור, מה למחוק, האם נדרשת הגנה מפני מחיקה ביעד.
- דרישות לכשל: מעבר ידני או אוטומטי, זמן אי-זמינות מותר.
- מגבלות: הצפנה במפתח משלכם, דרישות רגולטוריות למקום האחסון.
נעבור על הרשימה, נסמן פערים ואת מה שהכי משפיע על הארכיטקטורה. בתשובה נחזור לא במילים כלליות, אלא בתוכנית עבודה: שלבים, הערכת נפח, לוחות זמנים ליישום ונוהל חזרה לאחור, אם הסנכרון לא יתנהל לפי התרחיש.
תארו את המשימה בשתי פסקאות — לפי נתוני הפתיחה האלה נבין את ההיקף ונחזור עם הערכה ותוכנית.







