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

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

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

חלוקה של מערכת (process או service) למספר תהליכים או שירותים – הוא גם צעד שלא טומן בחובו Tradeoffs משמעותיים. לרוב – ה tradeoff בין צריכת זיכרון ל isolation – שבמקרים רבים עושה שכל.

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

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

מערכת מבוזרת הטרוגנית

אפשרות פעולה אחרת היא שגם שירות X וגם שירות Y נמצאים על שרתים A וגם B כך שתכולת שרתים אלו היא זהה. אפשרות זו נקראת מערכת מבוזרת הומוגנית

מערכת מבוזרת הומוגנית

מתי לבחור פרדיגמה הומוגנית?

שתי הגישות אפשריות ושתיהן יכולות לעבוד עבור כמעט כל מערכת. האם יש כללי אצבע שיעזרו לנו לבחור? – בהחלט כן!הכלל העקרוני הוא די פשוט: אם אפשר – בחרו בחלוקה הומוגנית (כל השרתים זהים וכוללים את כל השירותים).

יתרונות:

  • זמינות (high availability) גבוהה יותר, מכיוון ששני השרתים זהים. שרת A נפל – שרת B יוכל לספק את כל השירותים. בפרדיגמה ההטרוגנית כל שרת הוא single point of failure.
  • ניהול עומס (load balancing) מיטבי – כל שרת יכול לטפל בכל בקשה וכך ניתן לחלק את העומס בצורה מיטבית בין השרתים. בגישה ההטרוגנית ייתכן ששרת A עמוס לחלוטין, ולשרת B יש משאבים פנויים. קרי – לא ניצלתם את החומרה לתומה. חישבו על פיזור העומס לא רק ב load מרבי, אלא גם על השעות מהם יש עומס קטן יותר על המערכת.
  • יעילות תקשורת – אם שירות X ו Y זקוקים אחד לשני – הם יכולים לבצע קריאות לוקאליות בזכרון, שהן יעילות ובעלת latency קטן משמעותית מקריאה ברשת. אפילו אם בוחרים לתקשר על גבי http – הביצועים יהיו עדיפים במחשב מקומי.
  • תחזוקה קלה יותר (Maintainability). שיקול Operations. אנו יכולים להחזיק אותה חומרה ולנהל מלאי אחד של חלפים. אנו יכולים לנהל image יחיד, להתמודד עם בעיות של updates ו upgrade בצורה אחידה וכו'.
איך ממשים שני שירותים על אותו שרת? לרוב הפתרון פשוט כמו שהוא נשמע: אם מדובר על Servlet Engine – פשוט מתקינים את שני השירותים על אותו Container כשני קבצי war או ear נפרדים (שכל צוות בארגון יכול לפתח עצמאית).
אם השירותים הם בשפות תכנות שונות (נאמר Ruby ו Scala כמו ב [1]Twitter או C ו Java כפי שנפוץ במוצרים רבים) – פשוט מתקינים שני containers או אפליקציות על אותו השרת הפיסי. הרי ב Windows או Linux יש עשרות שירותים מותקנים, אז מונע מאיתנו להריץ עוד כמה?

עד כמה שנתקלתי המחסום העיקרי לאימוץ גישה זו – הוא פסיכולוגי. אולי התבנית מזכירה תבנית של שכפול קוד "The Mother of All Evil", אשר מעבירה בנו צמרמורת רק עם הזכרת שמה.

מתי לבחור בפרדיגמה הטרוגנית?

השיקולים העיקריים לפרדיגמה הטרוגנית הם:

  • שימוש במשאבים מיוחדים: חומרה מיוחדת ויקרה שזקוקים לה עבור שירות Y ולא עבור X וכך אפשר לחסוך בעלויות.
    • מקרה נפוץ יותר – צורך בזיכרון רב. לדוגמא: שירות Y משתמש ב in-memory Database וזקוק לכמה עשרות GB של זכרון כדי לפעול בצורה מיטבית. דוגמא נפוצה היא חוות זיכרון נוסח memcached או [terracotta[2.
  • השירות רלווני במיקום גיאוגרפי מסוים / מיקום מסוים ברשת. למשל: השירות מבצע sniffing על הרשת או חייב להיות מותקן במיקום מסוים כדי לגשת לשירותים שהוא זקוק להם.

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

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

"זיכרון, מכיוון ששירות Y דורש כ 2GB זכרון נוסף בכדי לרוץ".
מכיוון שזיכרון הוא זול כ"כ ועלות פיתוח של High Availability היא גבוהה כ"כ + ניצול מרבי של חומרה מחזיר מהר מאוד עלות של מעט זיכרון נוסף – טיעון זה לא נראה לי רציני.

הלקוחות שלנו רוצים לקנות שירות לראות את הקופסא שהם קנו.
שמעתי גם את זה. לפי דעתי זהו פידבק של אנשי מכירות או Professional Services ולא באמת לקוחות. לקוחות שאני מכיר מוטרדים מעלות התחזוקה הכוללת (TCO) שמושפעת יותר מ High Availability או אחידות החומרה. כשעבדתי בנייס, הפסדנו עסקאות כי השרת שלנו היה 3U (ר [3]) והשרת של המתחרה היה חלש קצת יותר אבל נכנס ב 2U (כלומר – קצת מקום איכסון היה מספיק משמעותי לעסקה). במידה וטיעון זה עלה – שווה לבקש לשוחח עם כמה לקוחות ולהבין במה מדובר.

"זיכרון, מכיוון ששירות Y דורש כ 20GB זכרון נוסף כדי לרוץ"
זהו אכן כלל-האצבע המצביע מתי הפרדיגמה ההטרוגנית עדיפה, אבל לפי דעתי כדאי לחשוב מעט ולא להחליט מייד. כמה עולה 20GB (ר [4]) זיכרון ומה מחיר חוסר-הזמינות?תזכורת: אלא אם מדובר בשרתי Unix עתיקים (שם הזיכרון יקר להחריד) – 20GB זיכרון הם לא דבר מאוד יקר. שווה לעשות את השיקול הכלכלי. לעיתים יהיה שווה לשים שרתים עם זכרון רב ולהשאר עם פרדיגמה הומוגנית (בעיקר ב cluster קטן). לעיתים באמת שווה לעשות את ההפרדה. במערכת עם מספר רב של שרתים (לרוב מערכת on-demand) ניתן לבחור בגישה מעורבת ולהנות מ-2 העולמות. לדוגמא: אם יש לי 12 שרתים אני יכול להקצות 8 לשירות X ו 4 לשירות Y (גישה הטרוגנית), אך כל קבוצה של שרתים תנוהל ב cluster שיספק לי high availability, load balancing וכו'.

ניהול משאבים הוגן או Resource Consumption Capping
זהו שיקול הגיוני: מספר שירותים במערכת שלנו עלולים לצרוך יותר משאבים ממה שאנו רוצים להקצות להם ולכן אנו רוצים להגביל את את השימוש בהם. גישה אחת לבצע את אכיפת שימוש המשאבים היא פריסה הטרוגנית של שירותים על מחשבים, למשל: יש לי 8 שרתים, 3 יוקצו לשירות X הבעייתי ו 5 לשירות Y. אכיפה כזו היא הקלה ביותר למימוש אך הגמישות לשנות את החלוקה ל 4:4 או 2:6 היא קטנה וייתכן שאותם 3 שרתים של שירות X לא יוקצו בצורה יעילה. פיתרון של Capping בתוכנה הוא פחות מדויק ודורש השקעה נוספת, אך יותר גמיש.
גישה מקובלת אחרת היא ליצור cluster הומוגני בו מספר קטן של שרתים להם רוצים לעשות Capping – מופרד ל cluster לוגי נפרד (כלומר: ה Load Balancer מתבקש לא להעביר להם תעבורה ע"פ כללים מסוימים). גישה מקובלת עבור ה crawler במערכות SharePoint או Batch Operations במערכות SAP.

"כי א' או ב' או ג'" או בקיצור "כי בא לי"
לעיתים השיקולים בארגון בו אנו עובדים הם רגשיים ולא ענייניים. דוגמא קלאסית הוא אפקט איקאה [5] – מישהו חשב ותכנון את פירוק השירותים ופתאום אתם באים עם רעיון דמיוני לשמור על פרדיגמה הומוגנית – והורסים הכל. ובכן, התמודדות עם מצב כזה הוא כבר דיון אחר, אבל בקיצור שווה לבדוק עד כמה רעה הגזרה ולעיתים גם לוותר. להיות צודקים יותר לא תמיד יביא אתכם למקום טוב יותר.

לסיכום: למרות שהגישה ההומוגנית היא מעט Counter Intuitive – היא טומנת בחובה עוצמה רבה שכדאי לעשות מאמץ ולנצל.

[1] סיפור מעניין בפני עצמו על Scalability.[2] החבר'ה מ Terracotta, חברה ישראלית, אוהבים לקרוא לחוות זיכרון אלו NAM – Network Attached Memory, על משקל NAS.

[3] חדרי שרתים בנויים מארונות הנקראים Rack מהם כל slot נספר כ U (אולי קיצור של Unit?). יחידות של 1U הן לרוב ציוד תקשורת כגון Router או Hub בעוד שרתים הם לרוב 2U. שרתים גדולים יותר יתפסו 3U או יותר.

[4] "איך לעזאזל מגיעים לצריכה של 20GB זיכרון?" אתם עשויים לתהות? לרוב כשיש Caches גדולים של מספר שירותים או In-Memory-Database.

[5] אפקט איקאה הוא המצב בו אדם שהשקיע עבודה מסויימת במוצר מתאהב בו ורואה תמונה מוטה של הדברים. במקור, האפקט מתואר כך שאדם יאהב יותר את הרהיט הפשוט מאיקאה שהרכיב בעצמו, על פני רהיט איכותי יותר שבהרכבתו לא היה מעורב. הנקודה המפתיעה היא שאדם השקיע חלק מהעבודה (איקאה) יתאהב במוצר בצורה חזקה יותר מזה שבנה את המוצר לבד מ Scratch.

תקשורת: מיהו התוכי האמיתי של האינטרנט המהיר?

הצחיק אתכם התוכי של בזק שנוסע במרכז ת\"א במסלול משלו?

זו פרסומת טובה. המסר מוחשי ומובן לכולם. בזק מתארת בפרסומים \"רשת נפרדת\", אך לא ברור מה בדיוק היא מספקת בפועל.עד כמה שידוע לי זהו routing מועדף (על בסיס static IP address) ויותר רוחב פס – לא יותר. אין שום רשת פיסית נפרדת – ואם הייתה, היא בוודאי לא הייתה נפרשת לכל קצוות תבל.

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

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

כנראה שתמונת האינרנט לא תהיה שלמה ללא הכרות עם חברת Akamai.
אקמיי (Akamai) חברה מסחרית היושבת במדינת מסצ\'וסטס (זו שקשה לומר את שמה) אחראית לנתון מדהים של 15 עד 30 אחוז* מתעבורת האינטרנט העולמית!
היא עושה זאת בעזרת 90 אלף שרתים המפוזרים ב 1800 אתרים (נכון למידע העדכני שמצאתי באינטרנט – והמספר רק גדל)
מי שמשלם על השירות הוא חברות האינטרנט שרוצות לספק תוכן מהיר (Apple, CNN, MTV ועוד). הרשת של Akamai אינה רשת פיסית (כמו כל דבר כמעט באינטרנט…) אלא רשת ווירטואלית ומשתמשת בעיקר בטכניקות הבאות:

Caching 
Akamai מבצעת Caching (דינאמי, שעם הזמן יכול להיות העתק של השרת המקורי) של תוכן משרת הלקוח לשרתים רבים ברשת שלה שפזורים בכל רחבי העולם. המשתמש שפונה לאתר הלקוח מופנה (ללא ידיעתו) לשרת הקרוב אליו גאוגרפית של Akamai.
אם התוכי של Akamai לא היה מביא את הסרט שאתם מורידים (אופס, כתבתי את זה?) לישראל או הסביבה – שום תוכי של בזק לא היה משיג 100Mbps בהורדת התוכן.
\"אבל חלק גדול מאוד מדפי האינטרנט הוא דפים דינאמיים\" יטען מפתח האינטרנט. נכון, אבל יש תמונות וקבצי מדיה (וידאו הוא כמעט חצי בכל תעבורת האינטרנט בבתים) שניתן לעשות caching בקלות ויש גם דרכים לבודד אלמנטים מהתוכן הדינאמי שלא משתנים ולשמור אותם ב cache.

Remote Proxy
למי שזוכר קצת תאוריה, יצירת קשר ב tcp (או http) דורשת 3 קריאות IP (הידוע כ three way handshake) ואם רוצים תוכן מאובטח (ssl) – עוד 4 קריאות handshake נוספות. במצב בו כל קריאת http/s מייצרת connection חדש – יעברו 3 או 7 הודעות ברשת בין השרת והלקוח עד שעמוד האינטרנט יתחיל לרדת (= latency). אקמיי יודעת להחזיק connection קבוע בין השרת של הלקוח לשרת המקומי שלה, לתת למשתמש לבצע handshake מול השרת המקומי שלה ומשם להשתמש ב connection קבוע. טכניקה זו פחות נדרשת עם העליה בתמיכה בפרוטוקול http 1.1 שהסדיר את שמירת ה connection הקיים בעזרת keep alive או pipelining. עדיין – פתרון מעורר מחשבה.

Improved Routing
Akamai טוענת שיש לה אלגוריתם גאוני (הרי הוקמה ע\"י בוגרי MIT, שאחד מהם, ישראלי, דני לוין נהרג בפיגועי 9/11  תוך מאבק בחוטפי אחד המטוסים***) ל routing משופר ברחבי האינטרנט, שמגיב גם הרבה יותר מהר לתקלות בתשתית התקשורת העולמית. עם פריסה ב 1800 אתרים ושליטה מרכזית בהם ייתכן שהיא צודקת (למרות שמבחנים הראו רק שיפור קל, בממוצע, על ה routing של האינטרנט עצמו).

Data Compression

יש חברות (CDN (Content Delivery Network אחרות (Akamai היא הגדולה, אך בהחלט לא היחידה) שמבצעות דחיסה יעילה במיוחד של תוכן דינאמי בין שרת הלקוח לשרת המקומי – לשיפור התעבורה. בוודאי יש עוד טכניקות רבות בשימוש…
ספציפית דחיסה נראית לי שיטה שלא תחזיק זמן רב בהתבסס על חוק נילסן: החוק שאומר שאמנם מעבדים מכפילים את כוחם כל 18 חודשים (חוק מור), אך הרשת מכפילה את קצב ההעברה פי 100 כל עשור (שזה יותר) – ולכן מתישהו (אנחנו עדיין מחכים) תשתנה הפרדיגמה ויהיה עדיף להעביר יותר תוכן ברשת בכדי לחסוך cycles של המעבד.

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

העתיד
כיום כבר יש לא מעט חברות CDN, אני מודע לאחת משלנו (קונטנדו הישראלית) והתחרות גוברת. Akamai שהבינה שהיא מאויימת על ידי רשתות P2P לגיטימות שצצו בשנים האחרונות (שהן זולות יותר ובעלות scale פוטנציאלי גדול יותר), התחילה לפעול גם בזירה הזו. Akamai מספקת Download Manager שאמור לשפר מהירות הורדה מאתרים מסוימים, אבל בעצם משתף את ההורדה P2P עם גולשים קרובים גיאוגרפית ששותפים לאותה ההורדה.
מאחר וחברות אבטחה הוסיפו למוצרהם יכולות CDN (דוגמא ישראלית: אינקפסולה**), הלכה Akamai והוסיפה יכולות אבטחה (בסיסיות) לשירותי ה CDN שלה. בזכות מערך השרתים האדיר השלה היא הצליחה לעצור ביולי 2009 התקפת DDoS אימתנית בקצב של 124Gbps על גוף ממשלתי בארה\"ב – קצב שהיה מפיל חברות רבות שנותנות שירותים דומים. בקיצור – נשמע שתהיה פה עוד נגיסה הדדית בין תחום האבטחה לתחום ה CDN.

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

עדכון: ניתן למצוא סיכום עברי על דו\"ח מצב האינטרנט של Akamai כאן.


* תלוי ב יום / שעה.

** כצפוי, אינקפסולה מספקת אבטחה חזקה מזו של Akamai, כמו ש Akamai מספקת CDN טוב בהרבה מזה של אינקפסולה.

*** תודה ל Kalen מאתר HWZone על הלינק לוידאו.