אפאצ'י פלינק הוא מנוע לעיבוד זרמי של נתונים בזמן אמת. רוב היישומים לעיבוד זרמים הם 'עם מצב'. זה אומר שהמצב מאוחסן ומשמש לעיבוד נוסף. באפאצ'י פלינק, המצב מנוהל דרך גב המצב שהוגדר. פלינק תומך בשני גבי מצב בפרודקשן. האחד הוא HashMapStateBackend
, והשני הוא EmbeddedRocksDBStateBackend
.
כדי למנוע אובדן נתונים ולהשיג עמידות בפני תקלות, פלינק יכול לשמור צילומי מצב של המצב לאחסון עמין. פלינק יכול להיות מוגדר לצלם או את כל המצב למיקום עמין או את השינויים מאז הצילום האחרון. הראשון נקרא בדיקת מצב מלאה, והשני נודע כבדיקת מצב מצמצמת.
במאמר זה, אנו מתכוונים להשוות HashMapStateBackend
עם בדיקה מלאה וEmbeddedRocksDBStateBackend
עם בדיקת מצב מצמצמת. מאמר זה מניח כי לקהל יש ידע עובד או ידע תיאורטי של אפאצ'י פלינק.
סקירת גב מצב של פלינק
כדי להבין את גב המצב של פלינק, חשוב לדעת את ההבדל בין מצב בתהליך ו צילומי מצב.
ה מצב בתהליך נודע כמצב העבודה של פלינק ומאוחסן מקומית. בהתאם להגדרת גב המצב, המצב נמצא בזיכרון המעריכה או בזיכרון מחוץ למערכת, עם אפשרות להתפוצץ לכונן המקומי.
ממנהצד השני, צילומי מצב (נקודת בדיקה או נקודת שמירה) מאוחסנים במיקום רחוק ומחזיקים בזמן. צילומי אלו משמשים לשחזור מצב העבודה של Flink במקרה של כשל בעבודה.
המצב בתוך התהולה עשוי לאבוד אם העבודה נכשלת. זה לא משפיע על שחזור העבודה אם הנקודת בדיקה מופעלת בעבודה. כאשר הנקודת בדיקה מוגדרת, המצב מושך מהאחסון הנמוך בזמן השחזור.
איזה מאחז מצב לבחור לייצור תלוי בדרישות היישום לקיבוץ, לאיחוד ולקידמה.
קיימים שני מאחזי מצב שApache Flink תומך בהם בייצור.
1. HashMapStateBackend
זהו מאחז מצב קל ב־Flink לניהול המצב המצומצם ומצב הפעלה במהלך עיבוד הזרמים. המצב מאוחסן בזיכרון הג'אווה באמצעות מבנה נתונים של HashMap. מאחר שהוא מאוחסן בזיכרון, המגבלה העיקרית כאן היא שגודל המצב המרבי מוגבל לגודל זיכרון הג'אווה. אין סידור סדרתי מעורב בכתיבה למצב או בקריאה מהמצב. לכן, זה מתאים לאפליקציות עם נמוך בעל השהייה, תקינות גבוהה ולא כל כך גדולות.
2. EmbeddedRocksDBStateBackend
המאחסן בצד השרת הזה מאחסן את הנתונים בתהליך בזיכרון המטמון של מסד הנתונים RocksDB. כברירת מחדל, RocksDB מאחסן את הנתונים בדיסק המקומי של מנהל המשימות. הנתונים מוספרים ומאוחסנים בזיכרון מחוץ לגודל ומושחתים לדיסק מקומי המחובר למנהל המשימות. פורמט הסידור תלוי בסוג המאחסן המוגדר ביישום.
עם מאחסן המצב הזה, כמות המצב שניתן לאחסן מוגבלת רק על ידי השטח בדיסק המחובר למנהל המשימות. אם ליישום יש מצב עצום ולא ניתן להכילו בזיכרון המטמון, זהו המאחסן המתאים. מאחר שהמאחסון משתתף, היישום יגיע להתמודדות עם זמני תגובה גבוהים ופונקציות נמוכות בהשוואה ל-HashMapStateBackend
.
סקירת מצב תמונתית
התמונת תמונה מייצגת את המצב הגלובלי של העבודה ב- Flink. זה כולל מצב של כל מקור הנתונים והמצב של כל אופרטורי המצב המחוזק של Flink לאחר עיבוד עד לנקודות האלו מהמקורות. הצפייה בצ'קפוינטים ב- Apache Flink היא מנגנון להשגת עמידות בפני תקלות על ידי שמירה מדי פעם על המצב באחסון רחוק ומוצפן.
במקרה של כשל בעבודה, Flink משיג את המצב המאוחסן מהאחסון המרוחק ומתחיל לעבד את נתוני הזרימה מהנקודה שבה הפסיק. Flink משתמש בצילומי סריקה של סוג המחסן חומרי. זהו נוסח של אלגוריתם צ'נדי-למפורט.
Flink תומך בשני סוגים של צ'קפוינג.
1. צ'קפוינג מלא
הצ'קפוינט המלא הוא כאשר כל המצב של העבודה של Flink נתפס ומאוחסן באחסון רחוק עמיד. במקרה של כשל בעבודה, העבודה משיבה מהמצב המאוחסן מראש. נדרשת כמות השטח לאחסון והזמן שנדרש לביצוע צ'קפוינט מושפעים לחלוטין מהמצב של היישום. הצ'קפוינט המלא עובד עם שני ה־HashMapStateBackend
ו־RocksDBStateBackend
.
צ'קפוינט השלמה
צ'קפוינט השלמה הוא גישה מאותגנת. במקום לצלם את כל המצב, Flink שומר רק את 'השינויים' שנעשו למצב מאז הצ'קפוינט האחרון. זה מפחית את העומס ברשת ולכן את הזמן שנדרש לביצוע צ'קפוינט. הצ'קפוינט מתרחש באופן מאותגן לחלוטין במקרה זה.
רק RocksDBStateBackend
תומך בצ'קפוינט השלמה. Flink משתמש במנגנון הפנימי של RocksDB לכך. אף על פי שביצוע צ'קפוינט לוקח פחות זמן מאשר צ'קפוינט מלא, במקרה של כשל בעבודה, זמן השחזור תלוי בגורמים רבים. אם הרשת היא מצוקה, זמן השחזור עשוי להיות גבוה יותר מהשחזור מצ'קפוינט מלא.
ניתוח
פרטי הצינור: צינור Apache Beam פועל על מנוע ה-Flink עם חלון קבוע של 10 דקות והצ'קפוינט מוגדר לרוץ כל 3 דקות. סוג הסידור המוגדר הוא AVRO.
- סוג האשכול: "m5dn.4xlarge"
- אחסון צ'קפוינט סופי: S3
- מספר המפתחות הייחודיים: 2K
Input rate 10k/s (~ 7.8 MB/s) | |||||||||
---|---|---|---|---|---|---|---|---|---|
הקלד | מספר: של TM |
פרלליזם | הקצאת Heap לכל TM |
שימוש ב-Heap לכל TM |
שימוש בזיכרון של Pod לכל TM |
שימוש ב-CPU לכל TM |
נקודת בדיקה גודל |
זמן | Checkpoint שימוש בזיכרון מנוהל על ידי Flink Memory |
מצב HashMap עם נקודת בדיקה מלאה |
1 | 1 | 10GB | 8.5GB | 11.1GB | 1.2 | 4GB | 50 שניות | 0 |
מצב RocksDB עם נקודת בדיקה צעדית ושימוש ב-AVRO |
1 | 1 | 3GB | 1.82GB | 4.63GB | 1.5 | 207MB | 3 שניות | 3GB |
Input rate 20k/s (~15.6 MB/s) | |||||||||
---|---|---|---|---|---|---|---|---|---|
הקלד | מספר: של TM |
פרלליזם | הקצאת Heap לכל TM |
שימוש ב-Heap לכל TM |
שימוש ב-Pod לכל TM |
שימוש ב-CPU לכל TM |
נקודת בדיקה גודל |
זמן | Checkpoint שימוש בזיכרון מנוהל על ידי Flink Memory |
מצב HashMap עם נקודת בדיקה מלאה |
2 | 2 | 10GB | 8.69GB | 11.2GB | 1.3 | 8.39GB | כ-50 שניות | 0 |
RocksDBState עם Incremental Checkpoint עם AVRO |
2 | 2 | 3GB | 1.87GB | 4.71GB | 1.4 | 404MB | 3 שניות | 3GB |
input rate 30k/s (~23.5 MB/s) | |||||||||
---|---|---|---|---|---|---|---|---|---|
סוג | לא: של TM |
פרלליזם | הקצאת Heap ל-TM |
שימוש ב-Heap ל-TM |
שימוש ב-Pod ל-TM |
שימוש ב-CPU ל-TM |
Checkpoint גודל |
משך ה-Checkpoint Flink ניהולי |
זיכרון ניהול HashMapState |
עם Checkpoint מלא | 3 | 3 | 10GB | 9.74GB | 11.2GB | 1.2 | 11.8GB | 65 שניות | 0 |
RocksDBState עם Incremental Checkpoint עם AVRO |
3 | 3 | 3GB | 1.72GB | 3.75GB | 1.4 | 576MB | 5 שניות | 3GB |
כפי שניתן לראות מהניסוי לעיל, משך ה-Checkpoint יורד עם Incremental Checkpointing. זה עשוי לסייע היטב בביצועי היישום.
סיכום
להלן סיכום של הניסוי.
HashMapStateBackend עם Checkpoint מלא | RocksDBStateBackend עם Incremental Checkpoint | |
העצירה של היישום | נמוך מאוד בגלל שהנתונים מאוחסנים כאובייקטים ב-Java בזיכרון המערים. קריאה וכתיבה אינם דורשים סידור נתונים. | מאחר שסידור נתונים משתתף בכל קריאה או כתיבה, זמן תגובה יהיה גבוה. |
הרמת קנה מידה | פחות קנה מידה עבור עבודות עם מצב גדול | קידומת רבה עבור עבודות עם מצב גדול ועם מצבים שמשתנים לאט |
אמינות בפני תקלות | גבוהה מאוד בפני תקלות | אמינות גבוהה מאוד בפני תקלות |
משך העצירה | משך העצירה גבוה כיוון שהעתקת הצילום נעשית עבור כל סט נתונים בזמן כל פעם. | משך ה-Checkpointing נמוך כיוון שרק הדלתא מאז ה-Checkpoint האחרון נשמרת. |
מורכבות השחזור | השחזור קל כיוון שרק צריך לטעון צילום אחד. | השחזור מורכב כיוון ש-RocksDB צריך לבנות את המצב ממספר עצירות והרבה תלוי במהירות הרשת. |
דרישות אחסון | נתמך על ידי HashMapStateBackend ו-RocksDBStatebackend. | נתמך רק על ידי RocksDBStatebackend. |
צילום מצב | שומר על כל המצב בכל נקודת בדיקה. | שומר רק את הדלתא מאז ההצלחה האחרונה. |
גודל ה-Heap | מאחר שהמצב מאוחסן ב-Heap לפני הצילום, דרישת ה-Heap גבוהה וצפויים מחזורי GC נוספים. | המצבים מאוחסנים באזור החוץ לזיכרון הראשי ואולי גם בדיסק המקומי, ולכן יש פחות מקום בזיכרון הראשי ופחות מחזורי GC. |
גודל מאחסן המצב | מוגבל על ידי הזיכרון המרבי שהוקצה ל-JVM. | גודל מאחסן המצב של RocksDB לא מוגבל על ידי המגבלה של הזיכרון המרבי של ה-JVM, אלא רק על ידי המקום הפנוי בדיסק. |
השפעת הביצועים | השפעה גבוהה על העיבוד מאחר שמדובר בצילום מלא. | השפעה נמוכה יותר על העיבוד מאחר שמדובר רק בדלתא שנצלמת. |
CPU | שימוש במעבד רק לצורך עיבוד ו-GC. אין סידור מאחסן מצב מעבר. | שימוש ב-CPU גבוה יותר בהשוואה לבדיקה מלאה עבור קצב נתונים כנדרש.
יש אפשרות לייעול את ניצול המעבד על ידי החלפת מכניזם תיקול מתאים. נבדקנו עם Avro וקיבלנו תוצאות הרבה טובות יותר בהשוואה ל-Kryo |
מקרה השימוש הטוב ביותר | מתאים לגודל קטן של מאחסן המצב ולמצבים שמשתנים בתדירות. | מתאים למצבים עם מאחסן גדול יותר ועדכון איטי של המצב. |
Source:
https://dzone.com/articles/apache-flink-full-checkpoint-vs-incremental-checkpoint