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

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

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

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

הגדרת טווח של שינוי גודל אוטומטי

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

Java

  • --numWorkers: המספר הראשוני של העובדים שזמינים כשהצינור מתחיל לפעול
  • --maxNumWorkers: המספר המקסימלי של העובדים שזמינים לצינור

Python

  • --num_workers: המספר הראשוני של העובדים שזמינים כשהצינור מתחיל לפעול
  • --max_num_workers: המספר המקסימלי של העובדים שזמינים לצורך הצינור

Go

  • --num_workers: המספר הראשוני של העובדים שזמינים כשהצינור מתחיל לפעול
  • --max_num_workers: המספר המקסימלי של העובדים שזמינים לצורך הצינור

במשימות סטרימינג שמשתמשות ב-Streaming Engine, הדגל --maxNumWorkers הוא אופציונלי. ערך ברירת המחדל הוא 100. במשימות סטרימינג שלא משתמשות ב-Streaming Engine, נדרש --maxNumWorkers כשמופעלת התאמה אוטומטית לעומס אופקי.

הערך ההתחלתי של --maxNumWorkers קובע גם כמה Persistent Disks מוקצים לעבודה. צינורות (pipelines) נפרסים עם מאגר קבוע של דיסקים קשיחים (Persistent Disks), שמספרם שווה ל---maxNumWorkers. במהלך הסטרימינג, מתבצעת חלוקה מחדש של דיסקים קשיחים קבועים כך שלכל worker מצורף מספר שווה של דיסקים.

אם מגדירים את הערך --maxNumWorkers, צריך לוודא שהערך מספק מספיק דיסקים לצינור העיבוד. כדאי לקחת בחשבון את הצמיחה העתידית כשמגדירים את הערך ההתחלתי. מידע על הביצועים של דיסק אחסון מתמיד (persistent disk) מופיע במאמר הגדרת דיסק אחסון מתמיד (persistent disk) ומכונות וירטואליות. ב-Dataflow החיוב הוא על שימוש בדיסקים לאחסון מתמיד ויש מכסות של Compute Engine, כולל מכסות של דיסקים לאחסון מתמיד.

כברירת מחדל, מספר העובדים המינימלי הוא 1 למשימות סטרימינג שמשתמשות ב-Streaming Engine, ו-(maxNumWorkers/15), מעוגל כלפי מעלה, למשימות שלא משתמשות ב-Streaming Engine.

עדכון טווח ההתאמה האוטומטית לעומס

במשימות שמשתמשות ב-Streaming Engine, אפשר לשנות את מספר העובדים המינימלי והמקסימלי בלי להפסיק או להחליף את המשימה. כדי לשנות את הערכים האלה, צריך להשתמש בעדכון של משימה בתהליך. מעדכנים את האפשרויות הבאות של המשרה:

  • --min-num-workers: המספר המינימלי של העובדים.
  • --max-num-workers: המספר המקסימלי של העובדים.

gcloud

משתמשים בפקודה gcloud dataflow jobs update-options:

gcloud dataflow jobs update-options \
  --region=REGION \
  --min-num-workers=MINIMUM_WORKERS \
  --max-num-workers=MAXIMUM_WORKERS \
  JOB_ID

מחליפים את מה שכתוב בשדות הבאים:

  • REGION: מזהה האזור של נקודת הקצה האזורית של העבודה
  • MINIMUM_WORKERS: המספר המינימלי של מכונות Compute Engine
  • MAXIMUM_WORKERS: המספר המקסימלי של מכונות Compute Engine
  • JOB_ID: המזהה של המשימה שרוצים לעדכן

אפשר גם לעדכן את --min-num-workers ואת --max-num-workers בנפרד.

REST

משתמשים בשיטה projects.locations.jobs.update:

PUT https://dataflow.googleapis.com/v1b3/projects/PROJECT_ID/locations/REGION/jobs/JOB_ID?updateMask=runtime_updatable_params.max_num_workers,runtime_updatable_params.min_num_workers
{
  "runtime_updatable_params": {
    "min_num_workers": MINIMUM_WORKERS,
    "max_num_workers": MAXIMUM_WORKERS
  }
}

מחליפים את מה שכתוב בשדות הבאים:

  • PROJECT_ID: מזהה הפרויקט של משימת Dataflow Google Cloud
  • REGION: מזהה האזור של נקודת הקצה האזורית של העבודה
  • JOB_ID: המזהה של המשימה שרוצים לעדכן
  • MINIMUM_WORKERS: המספר המינימלי של מכונות Compute Engine
  • MAXIMUM_WORKERS: המספר המקסימלי של מכונות Compute Engine

אפשר גם לעדכן את min_num_workers ואת max_num_workers בנפרד. מציינים אילו פרמטרים לעדכן בפרמטר השאילתה updateMask, וכוללים את הערכים המעודכנים בשדה runtimeUpdatableParams של גוף הבקשה. בדוגמה הבאה מבוצע עדכון של min_num_workers:

PUT https://dataflow.googleapis.com/v1b3/projects/my_project/locations/us-central1/jobs/job1?updateMask=runtime_updatable_params.min_num_workers
{
  "runtime_updatable_params": {
    "min_num_workers": 5
  }
}

בג'ובים שלא משתמשים ב-Streaming Engine, אפשר להחליף את הג'וב הקיים בערך מעודכן של maxNumWorkers.

אם מעדכנים עבודת סטרימינג שלא נעשה בה שימוש ב-Streaming Engine, ההגדרה של שינוי גודל אוטומטי אופקי בעבודה המעודכנת מושבתת כברירת מחדל. כדי להשאיר את ההתאמה האוטומטית לעומס מופעלת, צריך לציין את --autoscalingAlgorithm ואת --maxNumWorkers לעדכון המשימה.

הגדרת רמז לניצול העובדים

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

כדי לקבל שליטה רבה יותר בהתאמה אוטומטית לעומס, אפשר להגדיר את יעד ניצול המעבד (CPU) לערך בטווח [0.1, 0.9].

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

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

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

בדוגמה הבאה אפשר לראות איך משתמשים ב-worker_utilization_hint:

Java

--dataflowServiceOptions=worker_utilization_hint=TARGET_UTILIZATION

מחליפים את TARGET_UTILIZATION בערך בטווח [0.1, 0.9].

Python

--dataflow_service_options=worker_utilization_hint=TARGET_UTILIZATION

מחליפים את TARGET_UTILIZATION בערך בטווח [0.1, 0.9].

Go

--dataflow_service_options=worker_utilization_hint=TARGET_UTILIZATION

מחליפים את TARGET_UTILIZATION בערך בטווח [0.1, 0.9].

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

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

עדכון רמז הניצול

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

gcloud

משתמשים בפקודה gcloud dataflow jobs update-options:

gcloud dataflow jobs update-options \
  --region=REGION \
  --worker-utilization-hint=TARGET_UTILIZATION \
  JOB_ID

מחליפים את מה שכתוב בשדות הבאים:

  • REGION: מזהה האזור של נקודת הקצה האזורית של העבודה
  • JOB_ID: המזהה של המשימה שרוצים לעדכן
  • TARGET_UTILIZATION: ערך בטווח [0.1, 0.9]

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

gcloud dataflow jobs update-options \
  --unset-worker-utilization-hint \
  --region=REGION \
  --project=PROJECT_ID \
  JOB_ID

REST

משתמשים בשיטה projects.locations.jobs.update:

PUT https://dataflow.googleapis.com/v1b3/projects/PROJECT_ID/locations/REGION/jobs/JOB_ID?updateMask=runtime_updatable_params.worker_utilization_hint
{
  "runtime_updatable_params": {
    "worker_utilization_hint": TARGET_UTILIZATION
  }
}

מחליפים את מה שכתוב בשדות הבאים:

  • PROJECT_ID: Google Cloud מזהה הפרויקט של משימת Dataflow.
  • REGION: מזהה האזור של נקודת הקצה האזורית של העבודה.
  • JOB_ID: המזהה של העבודה שרוצים לעדכן.
  • TARGET_UTILIZATION: ערך בטווח [0.1, 0.9]

הגדרת רמז לגבי מקביליות של עובדים

כדי לטפל בהתאמה אוטומטית לעומס עם פעולות ארוכות שלא מסתמכות על מעבדים (CPU), כמו עומסי עבודה אינטנסיביים של למידת מכונה, אפשר להגדיר את רמז המקביליות של העובד באמצעות רמזי משאבים של Apache Beam. ההצעות האלה מעבירות את ההתאמה האוטומטית לעומס (automatic scaling) למצב אחר שממוטב לעומסי עבודה (workloads) שדורשים שימוש אינטנסיבי ב-GPU או לטרנספורמציות עם זמן עיבוד ארוך.

בדוגמה הבאה אפשר לראות איך לצרף רמז מקביליות לטרנספורמציה:

Java

pcoll.apply(MyCompositeTransform.of(...)
  .setResourceHints(
      ResourceHints.create()
          .withMaxActiveBundlesPerWorker(TARGET_PARALLELISM_PER_WORKER)))

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

Python

pcoll | MyPTransform().with_resource_hints(
  max_active_bundles_per_worker="TARGET_PARALLELISM_PER_WORKER")

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

בחירת ערך לרמז על מקביליות העובדים

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

בתרחישי שימוש אחרים, צינור הנתונים מוגבל על ידי הזיכרון או על ידי המעבד. בצינורות שמוגבלים בזיכרון, משתמשים במגבלת הזיכרון כדי לחשב את העיבוד המקביל המקסימלי. בצינורות שמוגבלים על ידי מעבד (CPU), מומלץ להשתמש במדיניות ברירת המחדל של התאמה אוטומטית לעומס (automatic scaling), במקום לספק רמז לגבי מקביליות.

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

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

היוריסטיקות של התאמה אוטומטית לעומס שדורשת שימוש אינטנסיבי ב-GPU

בהגדרה שדורשת שימוש רב במעבד הגרפי, שמסומנת באמצעות setting parallelism hint,‏ Dataflow לוקח בחשבון כמה גורמים כשמפעילים את התכונה 'שינוי גודל אוטומטי'. הגורמים האלה כוללים:

  • המקשים הזמינים. מפתחות הם יחידת הבסיס של מקביליות ב-Dataflow.
  • מספר החבילות הפעילות המקסימלי לכל עובד. ההמלצה הזו מתייחסת למספר המקסימלי האידיאלי של מקביליות העיבוד בתהליך העבודה.

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

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

כללי היוריסטיקה להתאמה אוטומטית לעומס (autoscaling) בסטרימינג

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

המערכת של Dataflow לוקחת בחשבון כמה גורמים כשמתבצעת התאמה אוטומטית של קנה המידה, כולל:

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

  • יעד לניצול המעבד (CPU). יעד ברירת המחדל לניצול ממוצע של המעבד הוא 0.8. אפשר לשנות את הערך הזה.

  • המקשים הזמינים. מפתחות הם יחידת הבסיס של מקביליות ב-Dataflow.

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

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

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

  • הגדלה על בסיס CPU משתמשת בניצול גבוה של CPU כקריטריון להגדלה.

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

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

הגדלת הרזולוציה. אם צינור סטרימינג נשאר עם עומס יתר עם מספיק מקביליות בעובדים למשך כמה דקות, Dataflow מבצע הגדלה של קנה המידה. ‫Dataflow מנסה לנקות את ה-backlog תוך כ-150 שניות של הגדלת קנה המידה, בהתחשב בתפוקה הנוכחית לכל עובד. אם יש עומס עבודה אבל אין לעובד מספיק מקביליות לעובדים נוספים, הצינור לא יגדל. (הגדלת מספר העובדים מעבר למספר המפתחות שזמינים לעיבוד מקביל לא עוזרת לעבד את הגיבוי מהר יותר).

הקטנת קנה מידה: כשהמידרוג האוטומטי מקבל החלטה על הקטנת קנה מידה, העומס הוא הגורם בעל העדיפות הגבוהה ביותר. הכלי להתאמת קנה מידה אוטומטית שואף להגיע למצב שבו אין יותר מ-15 שניות של עומס בערוץ. אם ה-backlog יורד מתחת ל-10 שניות, והניצול הממוצע של העובדים נמוך מיעד הניצול של המעבד, המערכת מצמצמת את קנה המידה של Dataflow. כל עוד העומס המצטבר סביר, הכלי להתאמת קנה מידה אוטומטית מנסה לשמור על ניצול המעבד קרוב לניצול המעבד היעד. עם זאת, אם רמת הניצול כבר קרובה מספיק ליעד, יכול להיות שהמידרוג האוטומטי לא ישנה את מספר העובדים, כי לכל שלב של הקטנת הקיבולת יש עלות.

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

מדדים

כדי למצוא את המגבלות הנוכחיות של שינוי הגודל האוטומטי של עבודה, שולחים שאילתה למדדים הבאים:

  • job/max_worker_instances_limit: מספר העובדים המקסימלי.
  • job/min_worker_instances_limit: המספר המינימלי של העובדים.

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

  • job/aggregated_worker_utilization: ניצול העובדים המצטבר.
  • job/worker_utilization_hint: רמז לגבי ניצול העובדים הנוכחי.

כדי לקבל תובנות לגבי ההתנהגות של המידרוג האוטומטי, שולחים שאילתה למדד הבא:

  • job.worker_utilization_hint_is_actively_used: מציין אם המידרוג האוטומטי משתמש באופן פעיל ברמז לניצול העובדים. אם גורמים אחרים מבטלים את הרמז כשדוגמים את המדד הזה, הערך הוא false.
  • job/horizontal_worker_scaling: תיאור של ההחלטות שהתקבלו על ידי המידרוג האוטומטי. המדד הזה כולל את התוויות הבאות:
    • direction: מציין אם המידרוג האוטומטי הגדיל את מספר המכונות, הקטין אותו או לא ביצע פעולה.
    • rationale: מציין את ההצדקה להחלטה של הכלי להתאמת קנה מידה אוטומטית.

מידע נוסף זמין במאמר בנושא מדדים של Cloud Monitoring. המדדים האלה מוצגים גם בתרשימי המעקב של התאמה אוטומטית לעומס.

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