מדריך לאפאצ'י מסוס

1. סקירה כללית

בדרך כלל אנו פורסים יישומים שונים באותו אשכול של מכונות. לדוגמא, מקובל כיום שיש מנוע עיבוד מבוזר כמו Apache Spark או Apache Flink עם מסדי נתונים מבוזרים כמו Apache Cassandra באותו אשכול.

Apache Mesos היא פלטפורמה המאפשרת שיתוף יעיל של משאבים בין יישומים כאלה.

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

2. שיתוף האשכול

יישומים רבים צריכים לשתף אשכול. בגדול, ישנן שתי גישות נפוצות:

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

למרות שגישות אלה מאפשרות ליישומים לפעול באופן עצמאי זה מזה, היא אינה משיגה ניצול משאבים גבוה.

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

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

Apache Mesos מסייע בהקצאת משאבים דינמית בין יישומים.

3. אפאצ'י מסוס

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

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

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

תמונה זו היא חלק מהתיעוד הרשמי של Mesos (מקור). פה, Hadoop ו MPI הם שני יישומים המשתפים את האשכול.

נדבר על כל רכיב המוצג כאן בחלקים הבאים.

3.1. מאסטר מסוס

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

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

3.2. סוכני מסוס

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

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

3.3. מסגרות מסוס

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

מסגרת של מסוס מורכבת משני מרכיבי משנה:

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

כל התהליך מתואר בזרימה זו:

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

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

Mesos מאפשר ליישומים ליישם את המתזמן והמבצע המותאמים אישית שלהם בשפות תכנות שונות. יישום Java של מתזמן חייב ליישםה מתזמן מִמְשָׁק:

מחלקה ציבורית HelloWorldScheduler מיישמת מתזמן {@Override public void registered (SchedulerDriver schedulerDriver, Protos.FrameworkID frameworkID, Protos.MasterInfo masterInfo) {} @Override public void ריק רשום מחדש (SchedulerDriver schedulerDriver, Protos.MasterInfo masterInfo) schedulerDriver, רשימת רשימות) {} @Override public void offerRescinded (SchedulerDriver schedulerDriver, OfferID offerID) {} @Override public void statusUpdate (SchedulerDriver schedulerDriver, Protos.TaskStatus taskStatus) {} @OverridDriverRiverDrive , Protos.SlaveID slaveID, בתים [] בתים) {} @ Override public void rute מנותק (SchedulerDriver schedulerDriver) {} @ Override public void slaveLost (SchedulerDriver schedulerDriver, Protos.SlaveID slaveID) {} @Override Schululer Driver .ExecutorID executorID, Protos.SlaveID slaveID, i nt i) {} @Override שגיאה בטלנית ציבורית (SchedulerDriver schedulerDriver, String s) {}}

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

באופן דומה, יישום של מנהל ביצוע חייב ליישם את מוציא להורג מִמְשָׁק:

מחלקה ציבורית HelloWorldExecutor מיישם את Executor {@Override public void registered (מנהל ExecutorDriver, Protos.ExecutorInfo executorInfo, Protos.FrameworkInfo frameworkInfo, Protos.SlaveInfo slaveInfo) {} @Override Public void reregeded (ExecutorDriver driver, ProtosveInfo) חלל ציבורי מנותק (מנהל התקן ExecutorDriver) {} @Override LaunchTask public void (מנהל התקן ExecutorDriver, משימת Protos.TaskInfo) {} @Override killTask ​​חלל ציבורי (מנהל התקן ExecutorDriver, Protos.TaskID taskId) {} ​​@Override בטל ציבורי בטל ציבור בתים [] נתונים) {} @Override כיבוי חלל ציבורי (מנהל התקן ExecutorDriver) {}}

נראה גרסה תפעולית של מתזמן ומבצע בקטע מאוחר יותר.

4. ניהול משאבים

4.1. הצעות משאבים

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

הצעת משאבים מורכבת משני חלקים - משאבים ותכונות.

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

ישנם חמישה משאבים מוגדרים מראש לכל סוכן:

  • מעבד
  • gpus
  • מ
  • דִיסק
  • יציאות

ניתן להגדיר את הערכים עבור משאבים אלה באחד משלושת הסוגים:

  • סקלר - משמש לייצוג מידע מספרי באמצעות מספרי נקודות צפות כדי לאפשר ערכים חלקים כגון 1.5 גרם זיכרון
  • טווח - משמש לייצוג טווח של ערכים סקלריים - למשל טווח יציאות
  • מַעֲרֶכֶת - משמש לייצוג ערכי טקסט מרובים

כברירת מחדל, סוכן Mesos מנסה לאתר משאבים אלה מהמחשב.

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

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

--resources = 'cpus: 24; gpus: 2; mem: 24576; דיסק: 409600; יציאות: [21000-24000,30000-34000]; bugs (debug_role): {a, b, c}'

כפי שניתן לראות, הגדרנו את הסוכן עם מעט מהמשאבים שהוגדרו מראש ומשאב מותאם אישית אחד בשם באגים שהוא של מַעֲרֶכֶת סוּג.

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

דוגמא שימושית יכולה להיות ל להוסיף סוכנים למדפים או אזורים שונים ואז לתזמן משימות שונות באותו מתלה או אזור כדי להשיג יישוב נתונים:

--attributes = 'rack: abc; zone: west; os: centos5; level: 10; keys: [1000-1500]'

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

4.2. תפקידי משאבים

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

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

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

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

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

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

4.3. הזמנת משאבים

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

ישנם שני סוגים של הזמנות:

  • הזמנה סטטית
  • הזמנה דינמית

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

 - מקורות = "cpus: 4; mem: 2048; cpus (baeldung): 8; mem (baeldung): 4096"

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

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

Mesos מקצה את כל המשאבים ללא כל תפקיד לתפקיד ברירת מחדל בשם (*). מאסטר מציע משאבים כאלה לכל המסגרות בין אם הם מנויים עליה ובין אם לאו.

4.4. משקולות ומכסות משאבים

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

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

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

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

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

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

5. מסגרת יישום

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

5.1. מעמד ראשי מסגרת

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

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

ראשית נוסיף תלות ב- Maven עבור Mesos:

 org.apache.mesos mesos 0.28.3 

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

main main static public (String [] args) {String path = System.getProperty ("user.dir") + "/target/libraries2-1.0.0-SNAPSHOT.jar"; CommandInfo.URI uri = CommandInfo.URI.newBuilder (). SetValue (path) .setExtract (false) .build (); מחרוזת helloWorldCommand = "ספריות java -cp2-1.0.0-SNAPSHOT.jar com.baeldung.mesos.executors.HelloWorldExecutor"; CommandInfo commandInfoHelloWorld = CommandInfo.newBuilder () .setValue (helloWorldCommand) .addUris (uri) .build (); ExecutorInfo executorHelloWorld = ExecutorInfo.newBuilder () .setExecutorId (Protos.ExecutorID.newBuilder () .setValue ("HelloWorldExecutor")) .setCommand (commandInfoHelloWorld) .setName ("שלום עולם (Java)") .setSource ("java"). לִבנוֹת(); }

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

לאחר מכן נפתח את המסגרת שלנו ונתחיל את המתזמן:

FrameworkInfo.Builder frameworkBuilder = FrameworkInfo.newBuilder () .setFailoverTimeout (120000) .setUser ("") .setName ("Hello World Framework (Java)"); frameworkBuilder.setPrincipal ("test-framework-java"); מנהל התקן MesosSchedulerDriver = חדש MesosSchedulerDriver (חדש HelloWorldScheduler (), frameworkBuilder.build (), טענות [0]);

סוף כל סוף, נתחיל את MesosSchedulerDriver שרושם את עצמו אצל המאסטר. לצורך הרשמה מוצלחת, עלינו להעביר את ה- IP של המאסטר כטיעון תוכנית טענות [0] למעמד הראשי הזה:

int status = driver.run () == Protos.Status.DRIVER_STOPPED? 0: 1; driver.stop (); System.exit (סטטוס);

בשיעור המוצג לעיל, CommandInfo, ExecutorInfo, ו FrameworkInfo הם כולם ייצוגי Java של הודעות פרוטובופ בין מאסטר למסגרות.

5.2. מתזמן יישום

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

ל Mesos 0.28 ומעלה, עלינו ליישם את מתזמן מִמְשָׁק:

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

ראשית נראה כיצד מתזמן מקצה משאבים למשימה:

@Override public void resourceOffers (SchedulerDriver schedulerDriver, List List) {for (Offer Offer: list) {List משימות = ArrayList חדש (); Protos.TaskID taskId = Protos.TaskID.newBuilder () .setValue (Integer.toString (LaunchTasks ++)). Build (); System.out.println ("השקת printHelloWorld" + taskId.getValue () + "Hello World Java"); Protos.Resource.Builder cpus = Protos.Resource.newBuilder () .setName ("cpus") .setType (Protos.Value.Type.SCALAR) .setScalar (Protos.Value.Scalar.newBuilder (). SetValue (1)) ; Protos.Resource.Builder mem = Protos.Resource.newBuilder () .setName ("mem") .setType (Protos.Value.Type.SCALAR) .setScalar (Protos.Value.Scalar.newBuilder (). SetValue (128)) ;

כאן הקצנו 1 מעבד ו- 128M זיכרון למשימה שלנו. לאחר מכן נשתמש ב- מתזמן נהג להשקת המשימה על סוכן:

 TaskInfo printHelloWorld = TaskInfo.newBuilder () .setName ("printHelloWorld" + taskId.getValue ()) .setTaskId (taskId) .setSlaveId (offer.getSlaveId ()) .addResources (cpus) .addResources (mem) .setExecutor. newBuilder (helloWorldExecutor)) .build (); רשימת offerIDS = ArrayList חדש (); offerIDS.add (offer.getId ()); משימות. להוסיף (printHelloWorld); schedulerDriver.launchTasks (offerIDS, משימות); }}

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

schedulerDriver.declineOffer (offer.getId ());

5.3. יישום מוציא להורג

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

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

בסעיף קודם דנו כיצד מסגרת מגדירה סוכן להתחיל בתהליך המבצע:

java -cp ספריות2-1.0.0-SNAPSHOT.jar com.baeldung.mesos.executors.HelloWorldExecutor

יש לציין, פקודה זו שוקלת HelloWorldExecutor כמעמד הראשי. אנו ניישם זאת רָאשִׁי שיטה ל לאתחל את MesosExecutorDriver שמתחבר עם סוכני Mesos כדי לקבל משימות ולשתף מידע אחר כמו מצב משימות:

מחלקה ציבורית HelloWorldExecutor מיישמת Executor {public static void main (String [] args) {MesosExecutorDriver driver = MesosExecutorDriver חדש (HelloWorldExecutor חדש ()); System.exit (driver.run () == Protos.Status.DRIVER_STOPPED? 0: 1); }}

הדבר האחרון שצריך לעשות עכשיו הוא לקבל משימות מהמסגרת ולהפעיל אותן על הסוכן. המידע להפעלת משימה כלשהי הוא עצמאי בתוך HelloWorldExecutor:

public void launchTask (מנהל ExecutorDriver, משימת TaskInfo) {Protos.TaskStatus status = Protos.TaskStatus.newBuilder () .setTaskId (task.getTaskId ()) .setState (Protos.TaskState.TASK_RUNNING) .build (); driver.sendStatusUpdate (סטטוס); System.out.println ("ביצוע משימה !!!"); status = Protos.TaskStatus.newBuilder () .setTaskId (task.getTaskId ()) .setState (Protos.TaskState.TASK_FINISHED) .build (); driver.sendStatusUpdate (סטטוס); }

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

במקרים מסוימים, מבצעים יכולים גם לשלוח נתונים חזרה למתזמן:

מחרוזת myStatus = "Hello Framework"; driver.sendFrameworkMessage (myStatus.getBytes ());

6. מסקנה

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

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

לבסוף ראינו יישום של מסגרת Mesos בג'אווה.

כרגיל, כל הדוגמאות זמינות ב- GitHub.