שיטות מומלצות לניסיונות חוזרים של משימות ולנקודות ביקורת

משימות ספציפיות או אפילו הרצות של משימות יכולות להיכשל מסיבות שונות. בדף הזה מפורטות שיטות מומלצות לטיפול בכשלים האלה, שמתמקדות בהפעלה מחדש של משימות ובנקודות ביקורת של עבודות.

שימוש בניסיונות חוזרים של משימות

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

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

תכנון הפעלה מחדש של משימות

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

לכתוב את הפלט למיקום אחר מזה של נתוני הקלט, כך שנתוני הקלט יישארו ללא שינוי. כך, אם העבודה תופעל שוב, היא תוכל לחזור על התהליך מההתחלה ולקבל את אותה התוצאה.

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

שימוש בנקודות ביקורת

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

מעת לעת, כותבים תוצאות חלקיות וציון של ההתקדמות שהושגה למיקום אחסון קבוע, כמו Cloud Storage או מסד נתונים. כשמתחילים את המשימה, כדאי לחפש תוצאות חלקיות בהפעלה. אם נמצאו תוצאות חלקיות, מתחילים לעבד מהמקום שבו העיבוד הפסיק.

אם העבודה לא מתאימה לשימוש בנקודות עצירה, כדאי לחלק אותה לחלקים קטנים יותר ולהריץ מספר גדול יותר של משימות.

דוגמה לנקודת ביקורת 1: חישוב פאי

אם יש לכם עבודה שמבצעת אלגוריתם רקורסיבי, כמו חישוב פאי עם הרבה מקומות אחרי הנקודה העשרונית, ומשתמשת במקביליות שהוגדרה לערך 1:

  • כדאי לשמור את ההתקדמות כל 10 דקות או כל פרק זמן אחר שמתאים לכם, באובייקט pi-progress.txt Cloud Storage.
  • כשמשימה מתחילה, שולחים שאילתה לאובייקט pi-progress.txt וטוענים את הערך כנקודת התחלה. משתמשים בערך הזה כקלט הראשוני לפונקציה.
  • כדי למנוע כפילויות באמצעות ביצוע מקביל או חוזר, או כדי להבדיל לפי תאריך הסיום, כותבים את התוצאה הסופית ל-Cloud Storage כאובייקט בשם pi-complete.txt או pi-complete-DATE.txt.

דוגמה לנקודת ביקורת 2: עיבוד של 10,000 רשומות מ-Cloud SQL

אם יש לכם עבודה שמעבדת 10,000 רשומות במסד נתונים רלציוני כמו Cloud SQL:

  • אחזור רשומות לעיבוד באמצעות שאילתת SQL כמו SELECT * FROM example_table LIMIT 10000
  • לכתוב רשומות מעודכנות בקבוצות של 100, כדי שלא תאבדו עבודה משמעותית אם העיבוד ייקטע.
  • כשכותבים רשומות, מציינים אילו רשומות עברו עיבוד. אפשר להוסיף לטבלה עמודה בוליאנית שעברה עיבוד, שמוגדרת ל-1 רק אם העיבוד אושר.
  • כשמשימה מתחילה, השאילתה שמשמשת לאחזור פריטים לעיבוד צריכה להוסיף את התנאי processed = 0.
  • בנוסף לניסיונות חוזרים נקיים, הטכניקה הזו תומכת גם בפיצול העבודה למשימות קטנות יותר, למשל על ידי שינוי השאילתה כדי לבחור 100 רשומות בכל פעם: LIMIT 100 OFFSET $CLOUD_RUN_TASK_INDEX*100, והרצת 100 משימות לעיבוד כל 10,000 הרשומות. ‫CLOUD_RUN_TASK_INDEX הוא משתנה סביבה מובנה שקיים בתוך הקונטיינר שמריץ משימות של Cloud Run.

השאילתה הסופית, שמשלבת את כל החלקים האלה, יכולה להיראות כך: SELECT * FROM example_table WHERE processed = 0 LIMIT 100 OFFSET $CLOUD_RUN_TASK_INDEX*100

המאמרים הבאים