יום שישי, 24 באוקטובר 2014

בלוגים עבריים ומקורות כלליים

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

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

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


עדכונים שוטפים

סוקר קבוע ובוחר מה לקרוא:
  • HackerNews (יש גרסה מסוכמת כ HackerNewsLetter, למי שהאתר הוא יותר מידי מידע בשבילו)
  • EchoJS - מעיין HackerNews של צד הלקוח, מוצלח למדי. יש גם אפליקציה לאייפון.
  • WebPlatformDaily - כנ"ל. עבר כעת למודל Fremium כך שגישה למה שלא פורסם היום - דורשת מנוי בתשלום.
  • Geektime - בו אני גם כותב חלק לא-מבוטל מהתוכן בתחום הפיתוח (הם מפרסמים פוסטים מהבלוג. רק שתדעו: תמיד הבלוג יותר מעודכן).
  • The Register - אתר חדשות "High Level" שהצליח להחליף אצלי כמה אחרים. יש לו מדור Data Center, Networking, תוכנה, ועוד. אני קורא אותו רק מהאייפד.


עוקב אחרי כנסים

כדי לוודא שאני מכיר לפחות את הנושאים ה"חמים" - אני עוקב אחרי תכנים של כמה כנסים.
קצת אחרי שהכנסים יוצאים לדרך, אני הולך לאתר שלהם וסורק את רשימת ה Sessions. האם יש נושאים שאין לי מושג מהם? אני מקדיש כמה דקות להשלים פערים. חלקים מה sessions בכנסים הללו, או לפחות רק המצגות - זמינים בחינם, ואני פשוט יכול לעבור עליהם ולסקור במה מדובר. בד"כ אני לא צופה יותר מ 2-3 sessions שמעניינים אותי במיוחד, מכל כנס.
  • QCON - כנס קטן, כמעט אינטימי ומאוד איכותי. עוסק בארכיטקטורה מעשית, אג'ייל, וטכנולוגיות חדשות. השתתפתי ב QCON London 2008 ומאז יש לי קוד שמתיר לי לגשת לכל התכנים (אני מניח שזה "לכל החיים")
  • GOTO - האח הקצת יותר גדול של QCON, אבל אופי הכנסים מאוד דומה. הוא רץ ברחבי העולם עם שינויים קטנים ואני רואה אחד בתחילת השנה, ואחד לקראת סופה - ואז החומר כבר מספיק שונה ממופע אחד למשניהו. עוד שבועיים אהיה בו בברלין.
  • Reversim Summit - הכנס הישראלי. משתדל להשתתף.
  • Berlin Buzzwords - אני לא יודע לקטלג אותו, אבל מצאתי שם כמה Sessions מאוד טובים.
  • OSCon - של O'Reilly. עוסק בכל מה שהוא קוד פתוח. זהו כנס גדול, ואני לא מגיע לעבור בכלל על כל רשימת ה session - רק על הפופולאריים ביותר. בד"כ מתפרסמים בכמה בלוגים שאני קורא סיכומים על ה Highlights בכנס - משם אני שואב references.
  • ThoughtWorks Technology Radar - זה בכלל לא כנס! זהו סיכום הניסיון בטכנולוגיות של חברת ThroughtWorks - חברת ייעוץ מאוד מכובדת בתחום התוכנה. הדו"ח יוצא פעמיים - שלוש בשנה, ואני משתמש בו בכדי לעקוב "מה חם".

פודקאסטים

שומע בדרך לעבודה, ולפעמים קצת משלים בערב על הספה. רובם בעברית.
  • רברסים - פודקאסט פופולארי של רן תבורי (עכשיו עצמאי) ואורי להב (אאוטבריין). יש להם כמה "סוגי" פרקים, סוג אחד בשם Bumpers הוא סיכום של עדכונים שונים בנושאי טכנולוגיה.
  • מובייל ובירה - למרות שאני כבר לא כ"כ בענייני מובייל, הפודקאסט הזה דיי סוגר לי את הפינה להתעדכן במה שקורה שם, ובצורה נחמדה מאוד.
  • טיפים בניהול - פודקאסט של אורי לביא וליאור כהן (שלמד איתי באוניברסיטה).
  • השבוע - פודקאסט על סטארט-אפים, שהתחלתי לעקוב אחריו לאחרונה. אני לא מקים סטארט-אפ, ולכן חלק מהתכנים קצת פחות משמעותיים עבורי.
  • JavaScriptJabber [אנגלית] - פודקאסט מוצלח על תכנות צד-לקוח
  • John ERP [אנגלית] - ענייני SAP, לא כ"כ רלוונטי למי שלא נמצא ב EcoSystem של החברה.
קשה לשמוע הכל, אני עוקב סלקטיבית.
את כל הפודקאסטים אני מוריד (הרשמה) מ iTunes.


בלוגים עבריים

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

ספציפית אני מפרסם רק את הבלוגים העבריים (אני עוקב אחרי הרבה לועזיים גם כן) - כדי לפרגן. אם אתם מוצאים בלוג שנשמע מעניין - נסו אותו.
  • Internet Israel של רן בר זיק מ HP Software, עוסק בווב - ומפרסם תדיר. כנראה הבלוג העברי הכי ידוע שמוכר לי.
  • מעונן חלקית - בלוג שעוסק בנושאי ענן. מפרסם מעט, אבל מעניין!
  • הבלוג הפתוח למנהל הפיתוח - הבלוג של משה קפלן (יועץ בתחום התוכנה). הבלוג משלב תכנים ניהוליים עם נושאים טכניים, לאחרונה בעיקר ענן ו High Scalability.
  • Eyal's Space - הבלוג של אייל ורדי, MVP של מייקורסופט שעשה קצת סוויטצ' ועכשיו הוא עוסק ומתמחה בעיקר ב AngularJS.
  • DevHeb - בלוג חדש של של רן תבורי (מ"רברסים") ועידו גרין (Developer Advocate בגוגל).
  • CR_Dev - פיתוח קליינט ובכלל
  • קוד נקי - הבלוג של שי מסיסטרנו, שמפרסם פוסטים קטנים ונקודתיים על יכולת כלשהי בפיתוח ווב. לאחרונה מתמקד ב ECMAScript 6 (הג'אווהסקריפט החדש).
  • חופש החיפוש - בלוג חצי טכנולוגי על נושאי חיפוש בגוגל (ובכלל)
  • הבלוג של אשר ברק - עוסק בנושאים טכנולוגיים מגוונים
  • הבלוג של עודד לקהילת SAP בישראל - רלוונטי למי שב EcoSystem של חברת SAP.

שכחתי מישהו? (הכוונה: בלוגים משמעותיים בעברית + כאלו שעדיין "חיים", לא בלוגי-עבר - שיש לי רשימה ארוכה שלהם)


ספרים

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


Video Tutorials

אם אני רוצה להכנס לנושא ספציפי (ספרייה, שפה, וכו') מהר - הדרך שגיליתי שהיא By-Far הכי יעילה עבורי היא Video Tutorial. הנושא והפרטים פשוט "מוזרקים" למוח בקצב מהיר יותר מכל מדיום אחר. אני משתמש ב Pluralsight (יש לי מנוי שקיבלתי בכנס) או Linda (קצת פחות מוצלח - שיש לי מנוי מהעבודה).
זה קצת פריקי אולי, אבל אני נוהג לראות את הסרטים בהאצה של x1.25 עד x1.5. המרצים לרוב מדברים ל-א-ט, ואני קצר בזמן.

לנושאים SAP-ים, אני משתמש ב OpenSAP שיש בו כמה קורסים טובים - אבל סה"כ החומר בו הוא כ 10-12 קורסים.

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


סיכום


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

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

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

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

הערת אגב:
אני עובד לא-מעט עם מהנדסים גרמנים (חברת SAP, דא). דבר מאפיין שניתן בקלות לומר לזכותם, הוא שהם נוטים להיות יסודיים יותר ממהנדסים ישראליים. בישראל - הרבה יותר מקובל להתקדם עם נושא ב"בערך": מבינים קצת - ומתחילים לרוץ. כשאני עובד עם המנהנדסים הגרמניים ב SAP, הרבה יותר נפוץ למצוא אנשים שמבינים לעומק את הטכנולוגיות והסביבה שבהם הם עובדים.
שוחחתי על כך פעם, עם בחור גרמני, שהציע הסבר כזה: מכיוון שכלכלת גרמניה היא גדולה ועשירה, הרבה מאוד ספרים טכניים נחשבים (DDD, Lean Startup, Design Patterns, וכו') - מתורגמים לגרמנית, מה שהופך את הידע המקצועי לזמין יותר עבור דוברי גרמנית.
האם זה באמת הגורם? אני מניח שזה פקטור, ביחד עם תרבות קצת שונה מהתרבות בארץ (למשל: גאווה לאומית ב "German Engineering". מעולם לא שמעתי דברי שבח על "הנדסה ישראלית").

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

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


ליאור


יום רביעי, 15 באוקטובר 2014

מהי התשתית (Framework) הטובה ביותר? [דעה]


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

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

אני הולך להמליץ לכם על ה Framework הטוב ביותר שנתקלתי בו, באמת!




האם זה Spring Framework?

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


בטח מדובר ב AngularJS - אין דבר חם יותר בשוק היום!

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


המסקנה הברורה היא בטח MeteorJs - מה יכול להיות יותר יעיל מ Angular?!

  - רעיון טוב, אבל לא.


מתחכם?

  - לא ממש. אין לי כוונה לסיים את הפוסט הזה עם קלישאה (נכונה) כמו: "כל כלי מתאים למשימה אחרת"...


אני רוצה להמליץ לכם באמת על משהו שהוא מבחינתי תובנה. לצורך הדוגמה (נאמר שמפתחים בצד-הלקוח) אציע לכם את התהליך הבא:
  1. לכתוב את המודול הראשון / הפרויקט הראשון ב Backbone.js
  2. במידה ויש הצלחה - לזרוק את Backbone. אם אין הצלחה - להמשיך איתו עוד סיבוב.
  3. לאחר שזרקתם את Backbone - ללמוד AngularJs, MeteorJs או React.js - והתחיל לכתוב בהם.

ברור לי שעל-פניה זוהי עצה מטופשת למדי!


אז מהי התשתית אותה אני מציע?
התשתית היא לא אף אחת מאלו שהוזכרו למעלה.







זוכרים את "הסיפור שאינו נגמר"?

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

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

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

(איזה סיפור נהדר!)




Opaque



Efficient Frameworks

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

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

שנים אחר שנים, עבדתי עם מפתחים שסיפקו להם "תשתיות עם הגנה בפני-חוסר ידע" - בכדי לדלג על שלב ההבנה של מה שמתרחש סביבם. אנו קוראים לזה Transparency (שקיפות), אך זה בעצם Opaqueness (אטימות) - לא יודעים מה מתרחש בפנים. בורות זו היא נוחה ב 95% מהזמן, והרסנית ב 5% מהזמן שנותר.

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

עבדתי בחברה, שהחליטה שהמפתחים שלה (שהוגדרו כעילויים, ברובם) לא מסוגלים לכתוב ב ExtJS - ספרייה לפיתוח צד-לקוח, שכבר בעצמה מחביאה כמעט כל מה שקורה בצד הלקוח במקבץ מרשים של רמות-הפשטה.
מה עשו? כתבו Framework נוסף, מבוסס XML, כדי להחביא עקרונות של ExtJS כמו MVC, ניהול אירועים, ועוד. "רק תגדיר איך המסך נראה ומה קורה כשלוחצים על כפתור" - הייתה שיטת העבודה.

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

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

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



Transparent


Effective Frameworks

יש תשתיות אחרות, שמבזות את כל מה שנחשב כזריז (efficient).
כדי לכתוב בהן משהו - יש לכתוב יותר שורות קוד. הן לא מגינות על המפתחים, והן משקפות למפתח את מה שקורה "בפנוכו", בלי שום התחשבות בבלבול הרב שיכול להיווצר מכל הידע הזה.

תשתיות אלו הן תשתיות שהן באמת Transparent - רואים את כל מה שקורה. דוגמאות נפוצות יהיו Node.js (כמובן), Backbone.js (אותה ציינתי קודם), וגם מערכת ההפעלה Linux (בה כ"כ הרבה הוא גלוי למשתמש).

הזריזות של ה Frameworks ה Efficient, מפנה את עצמו ללמידה-מעמיקה מואצת של המשתמש. כשכותבים ב Backbone.js מחברים "בידיים" את ה View ל Controller וקושרים "בידיים" את האירועים. זו עבודה - אבל כל מי שכותב ב Backbone.js מבין דיי מהר כיצד פועל ה MVC בעולם של Backbone.

שאנו מגייסים עובדים, אנו מחפשים את "הטוב ביותר", אבל המנגנונים שאנו יוצרים (מכוונה טובה) - שוחקים חלק גדול מהם. פעם אחר פעם ראיתי מתכנתים שמתקבלים לעבודה, אבל לאחר 3-4 שנים, כבר לא מסוגלים לעבור מחדש את אותם ראיונות ומבחנים. התהליך השוחק של עבודה בתשתיות "מגוננות" גורמות למתכנת לאבד את הברק, ולהפוך לחצי-טכנוקרט. וכן, אולי הוא עבד בכמה שנים הללו 15% יותר מהר.

הייתה לי הזדמנות נדירה בפרויקט כלשהו, לשים בצד את AngularJS לטובת Backbone.js. הצוות לא היה מיומן בפיתוח צד לקוח (עבר הדרכה, אך ללא ניסיון משמעותי). בעזרת Angular הצוות היה מתרגל לספרייה תוך חודש - ורץ מהר. עם Backbone.js הצוות אמנם "התניע" בשבועיים - אך רץ יותר לאט.

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

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

אם כן - מה עדיף?
להיות מהיר, או להיות יעיל?

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

גם חשוב מאוד לספק Delivery ולהתקדם מהר. כמה ארגונים יכולים "לספוג" מפתחים שמפתחים יותר לאט? נכון גם לשאול: כמה ארגונים יכולים "לספוג" מאסה של מפתחים שרק "מסתדרים" ולא ממש מבינים מה הם עושים?


אני מאמין, שהתשתית (Framework) הכי טובה שיש היא התשתית האנושית - מפתחים שמבינים מה הם עושים. אני לא חושב שמישהו יחלוק על כך: כולנו רואים כיצד המפתחים הבולטים יכולים לעשות כל-כך הרבה יותר. אני גם טוען שהתשתית האנושית לא יכולה להירכש רק על ידי גיוסים והדרכות - כפי שמקובל בתעשייה. אני מאמין שהדרך לשם היא לבחור במתכוון ובצורה אסטרטגית בסביבות עבודה בעלות-שקיפות (Transparency) בכל פעם שמתמודדים עם Domain חדש או טכנולוגיה חדשה.
סביבות בעלות פריון גבוה (נאמר: AngularJS או RoR) הן הסביבות המתאימות לאלו שכבר מבינים ועברו את שלבי הלמידה - ולא כתחליף ללמידה משמעותית של הטכנולוגיות, וסביבת-הריצה של המערכת.

אם יש לכם זמן לכתוב תשתית MVC בעצמיכם, ואז לזרוק אותה - אדרבא! זו למידה מצוינת.

אם אתם יכולים להתחיל בעבודה בתשתית Transparent בכדי להגביר למידה, ורק אז לעבור תשתית היעילה - עדיף. קודם תבנו את התשתית האנושית של ההבנה - ורק אח"כ תתמקדו בתשתית התוכנה שחוסכת שורות קוד.

הנה הנוסח, שהופיע בתחילת הפוסט:
  1. לכתוב את המודול הראשון / הפרויקט הראשון ב <ספרייה בעלת-שקיפות>.
  2. במידה ויש הצלחה בלמידה - לזרוק את ה <ספרייה בעלת-השקיפות>. אם אין הצלחה - להמשיך עוד סיבוב של למידה.
  3. לאחר שזרקתם את <ספרייה בעלת-השקיפות> - הרשו לעצמכם לעבוד ל<ספרייה אטומה שמתמחה ביעילות>.
יכול להיות שב domains מסוימים (למשל: עבודה ע"פ פרויקטים) - גישה זו כבר איננה משתלמת.

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


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


שיהיה בהצלחה!!



-

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


----

[א] התרגום "זריז" ל Efficient מתאים לי יותר למטרות הפוסט. בלשנים - התמודדו!



יום רביעי, 8 באוקטובר 2014

Spring-JDBC: שדרוג קטן לעבודה ב JDBC

בפוסט (קצר) זה אני רוצה לשתף בכלי שהתחלנו להשתמש בו לאחרונה - Spring JDBC.

נכון, לספרינג יש גם כלים ל JPA / חיבור ל Hibernate, - אבל לפעמים לא רוצים לעבוד עם ORM - אלא עם JDBC פשוט.

(כדרך אגב, ה Suite של ספרינג כולל רכיב בשם iBatis שהוא הפשטה / אוטומציה מעל JDBC. קצת יותר מ JDBC Templates אותם אנו סוקרים בפוסט זה -  וקצת פחות מ ORM. עקרון הבסיס שלו הוא קשירה של SQL Statements שכתב המפתח לאובייקטי Java וניהול ההפעלה שלהם.)

בכל מקרה אנו רוצים לעבוד עם הבסיס - עם Spring-JDBC וכלי ה JDBC Templates שלו.

JDBC Templates מסייעים בפישוט הגישה לבסיס הנתונים בכך שהם מטפלים בכמה נושאים:

  • פתיחה / סגירה של משאבים מול בסיס הנתונים (Connection, Statement, וכו') - נושא שטיפול לא נכון בו יכול לכלות את ה connection pool ולגרום לקריסה של מערכות.
  • פישוט ניהול Transactions  - על בסיס Spring Transactions
  • עטיפה של Exceptions טכניים של JDBC ב Exceptions יותר ידידותיים. למשל: לקבל CannotGetJdbcConnectionException במקום SQLException עם ErrorCode סתום כלשהו.
 סה"כ Spring-JDBC היא שכבת ריפוד קלה לעבודה כמעט ישירה מעל JDBC.




הקמת סביבת העבודה


צעד ראשון נדרש הוא שיהיה לנו חיבור לבסיס הנתונים (ושיהיה גם בסיס נתונים, כמובן. אני מניח שיש לכם). JDBC Templates עובדים מול DataSource - שהוא הממשק של ג'אווה ל Factory המייצר DB Connections.
בואו נתחיל בהגדרת DataSource שיהיה מחובר לבסיס הנתונים.

הערה: חילקתי שלב זה ל2 וריאציות :אפליקציה שהיא Standalone, ואפליקציה שרצה על Application Server.


אפליקציית Standalone

ניתן תאורטית להשתמש בקובץ ה XML של ספרינג כקובץ קונפיגורציה. למשל: להגדרת הפרמטרים של החיבור לבסיס הנתונים.
בפועל - זה לא רעיון כ"כ מוצלח: לקוח (איש IT) שיידרש לשנות קובץ יכול בקלות להסתבך או/ו להרוס משהו. קונפיגורציה כמו חיבור לבסיס הנתונים, שסביר שנצטרך לקנפג עבור כל התקנה - עדיף לשים בקובץ חיצוני ופשוט, כזה שיהיה זמין בקלות לכלי קונפיגורציה כמו chef או puppet. למשל: קובץ properties (המורכב מ keys ו values מופרדים ע"י הסימן "=").

הנה דוגמה לכזו תצורה:


  1. אנחנו מבקשים מ Spring לטעון ל ApplicationContext קובץ Properties חיצוני. כל ערכי הקובץ יתווספו ל context של ספרינג. שימוש ב classpath יכול להכשל אם החיפוש של ספרינג החל ב root classpath שונה, למשל של ספריית ה test - ושימוש ב *classpath יחפש אחר הקובץ בכל ה roots של ה classpath.
  2. באפליקציה שהיא Standalone הייתי רוצה לקבל יכולות בסיסיות של Connection Pooling, אותן נוכל לקבל מ Apache Commons ע"י שימוש ב BasicDataSource.
  3. בעת חיסול האפליקציה נקרא ל ()DataSource.close שגורם לסגירה מסודרת של כל ה connections שנותרו.
  4. השמת משתני ה "Connection String" ל dataSource נעשית ע"י ספרינג שמשתמש ב Setters הקיימים של מחלקת ה BasicDataSource בכדי לקבוע את הערכים, שבשלב 1 נטענו לסביבה.
ובכדי להשלים את התמונה - הנה קובץ ה properties:



סביבת Application Server

אם אתם לא הקוד הראשון שרץ על ה Application Server - סביר שמישהו כבר רשם DataSource, טיפל ב connection pooling וכו', ורשם אותו ל JNDI. אתם רק צריכים להתייחס אליו. למשל:


פשוט!

מרגע זה נועל להתחיל לעבוד עם Spring-JDBC.



JdbcTemplate


היכולות הבסיסיות של Spring-JDBC נגישות דרך שימוש במחלקה JdbcTemplate. מחלקה זו מנהלת את ה Connection, Statement וה ResultSet של JDBC ועוטפת את ניהול השגיאות.

נגדיר bean של JDBC Template ונשתמש ב DataSource שהגדרנו קודם:



הנה דוגמת קוד לשימוש ב JdbcTemplate כחלק מ DAO (אובייקט גישה לנתונים, קיצור של Data Access Object):



  1. נגדיר SQL Statement של INSERT עם מקום להכנסת ערכים (סימני השאלה).
  2. KeyHolder (או המימוש הפשוט GeneratedKeyHolder) היא מחלקה של Spring-JDBC המשמשת כמבנה נתונים שמחזיק key של הטבלה (מספר columns, כמו Primary Key). בפעולות Insert - ערך ההחזרה הוא ה key שניתן לרשומה החדשה.
  3. המתודה update משמשת לכל פעולת SQL של עדכון (יצירה, מחיקה, עדכון). במקרה שלנו - יצירה (INSERT).
  4. אנו מצהירים מהם ה colums שאנו רוצים לקבל בחזרה מפעולת העדכון. זהו ה primary key שנקבע ע"י בסיס הנתונים.
  5. אנו מבצעים השמה מתוך ה Domain Object (במקרה שלנו: Person) לתוך ה prepared Statement, כדי למלא את ערכי ה ?,?,? ב SQL Statement - ואת הטיפוסים שלהם.

שימו לב שאין לנו בקוד טיפול בשגיאות, ואין את סגירת ה connection / statement - שהם error prone, וטיפול לא נכון בהם יכולים לפגוע ביציבות המערכת. כל אלו מטופלים עבורנו ע"י המחלקה JdbcTemplate.



NamedParameterJdbcTemplate


אני רוצה להציג בקצרה, Template של Spring-JDBC שהוא טיפה יותר "מפנק".
מעצבן אתכם לראות את הקוד של השמה של ערכים ל prepared Statement עם טיפוסים? הנה דרך מעט יותר אלגנטית לעשות זאת.

בכדי לגוון (ולהראות את ה RowMapper) בחרתי בשאילתה שמחזירה נתונים (SELECT) ולא מבצעת עדכון.



  1. במקרה הזה אין לנו ?,?,? בשאילתה, אלא placeholders המתחילים בסימן ":".
  2. SqlParameterSource הוא מבנה נתונים של Spring המתאים ל NamedParameterTemplate. הוא משמש כפרמטר לפעולות השונות של ה NamedParameterJdbcTemplate.
  3. הפעם אנו לא עושים פעולת update כי אם query. ה RowMapper היא מחלקה שתפקידה לתרגם את ה ResultSet ל Domain Object. במקרה זה יצרנו אותה כ Anonymous Class.
  4. השמה "סיזיפית" של ערכים. אני לא מכיר דרך יעילה בהרבה לעשות זאת.


שיהיה בהצלחה!




יום שבת, 4 באוקטובר 2014

להבין Virtualization

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

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

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

רעיון הוירטואליזציה קיים ברמות הפשטה שונות:
  • זיכרון וירטואלי - הוא מימוש של וירטואליזציה לזיכרון. הוא מבצע multiplexing (חלוקת משאב פיסי אמיתי לכמה תהליכים אורחים במקביל) וגם emulation (בכך שהוא מנהל כתובות מדומות של הזיכרון הוירטואלי עמם התהליכים האורחים עובדים).
  • מנגנון ה LVM של לינוקס (קיצור של Logical Volume Manager) הוא דוגמה לוירטואליזציה של הדיסק. האופי שלו הוא אחר: הוא מבצע aggregation בכך שהוא גורם לכמה דיסקים פיסיים להראות כמו דיסק לוגי יחיד. זו עדיין וירטואליזציה.
  • מנגנון ה NAT (קיצור של Network Address Translation) של פרוטוקול IP, המשמש רכיבי רשת כמו proxy או reverse proxy בכדי להסתיר כתובות רשת אמיתיות של מחשבים - הוא דוגמה לוירטואליזציה של הרשת.
  • X-Server או VNC של לינוקס / Remote Desktop של חלונות - הם דוגמאות לוירטואליציה של ה Desktop. זהו עולם דיי עשיר עם פתרונות כמו App-V של מייקורוסופט ש"מזרים" אפליקציה שרצה בשרת מרוחק - למחשב השולחני המקומי (זו בעצם Application Virtualization).

בפוסט זה ארצה להתמקד בויאטואליזציה של החומרה כולה (זיכרון, דיסק, רשת, וכו') - מה שרוב האנשים מכירים פשוט כ "Virtual Machine" או "VM".




במהלך הפוסט אנסה לענות על שאלות כגון:
  1. כיצד, בפועל, טכנולוגיות הוירטואליזציה חוסכות לארגון ה IT כסף רב?
  2. מה ההבדל בין hypervisors מ"טיפוס 1" ל hypervisors מ"טיפוס 2"? וכיצד בוחרים את העדיף לסיטואציה?
  3. מהי Paravirtuallization ומהם Linux Containers (שעושים כ"כ הרבה רעש בשנתיים האחרונות)??
  4. למה לקח כ"כ הרבה זמן לויטרטואליזציה לתפוס מקום מרכזי בתעשייה? אתם יודעים, כמעט 40 שנה?
  5. מי הם Popek ו Goldberg - ומה הקשר שלהם לכל הסיפור?


מוטיבציה


אנסה להעביר את המוטיבציה בעזרת סיפור קצר. בסיפור שלנו יהיה ארגון עם Data Center שכולל כמה שרתים שונים:
  • שרת קבצים (shares)
  • שרת ווב
  • שרת e-commerce
  • שרת דואר (Exchange)

(לצורך פשטות הסיפור אתאר רק 4 שרתים. בסביבה אמיתית סביר שיהיו הרבה יותר).


מקור: VMWare


במשך השנים נוצר הסטנדרט בו כל שרת רץ על "קופסה" (כלומר: מחשב פיסי) משלו.
ניסיונות שהיו במשך השנים להריץ כמה תוכנות שרת על אותו שרת פיסי (מה שנקרא "server consolidation") נגמרו לרוב בחוסר שביעות-רצון של האחראים על תוכנות השרת (גם אם אותו האדם אחראי על שתי מערכות שונות). מדוע?
  • Sandboxing: תקלה בשרת הדואר יכולה לגרום לקריסה של מערכת ההפעלה - ולא רוצים ששרת הווב או המסחר האלקטרוני לא יהיו זמינים בגללו. אולי שרת הדואר דורש עדכון של מערכת ההפעלה שגורם לבעיה חדשה בשרת הקבצים?
  • אמינות: כאשר כל שרת רץ על עותק שלו של מערכת ההפעלה - פשוט יש פחות תקלות. שני שרתים דורשים הגדרות תצורה מעט שונות - שלא אופטימליות או מוכרות עבור תוכנת השרת השנייה.
המציאות בפועל הייתה שאנשי ה IT דרשו מהארגון "קופסה לכל שרת" כתנאי עבודה בסיסי.
הקצאה של "קופסה לכל תוכנת שרת" סיפקה את היתרונות המצופים:
  • זמינות: שדרוג / עדכון של תוכנת שרת אחד, לא משפיעה על שרתים אחרים. 
  • דרישות סביבה שונות: שרת הדואר רץ על "חלונות", שרת המסחר על איזו גרסה של UNIX ושאר השרתים רצים על לינוקס בכלל. דרישות חומרה בד"כ אפשר לכנס בקלות רבה יותר.
  • יתרונות אבטחה: קבלת הרשאות root על מחשב אחד, לא משפיעה על הגישה למחשבים האחרים.
כל זה טוב ויפה - אבל יקר. 
יקר בכלל הכפילות של החומרה שחלק גדול מהזמן נמצאת ב Utilization נמוך. אם שרת הווב, דורש לשעה בחודש כח עיבוד X, יש לספק לו כח עיבוד זה גם אם שאר החודש הוא זקוק לכח עיבוד של X/12 או אפילו X/60.

בנוסף: כשקונים שרת פיסי עבור תוכנה חדשה - כמה חומרה יש לקנות? האם מתכננים לחודש הראשון של השימוש או לשנה אח"כ? בתעשייה נוצרה פרקטיקה בשם Sizing שמטרתה להעריך כמה חומרה תידרש, פרקטיקה מאוד לא מדויקת בה טעות של עד פי 2 - נחשבת כהצלחה.

שרתים פיסיים שרוב זמנם עובדים על כ CPU 10% - היו תמונה מקובלת.

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

עונתיות בשימוש במשאב מחשוב




הערך של וירטואליזציה


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

מה קורה כאשר השרת הפיסי כושל? האם לא פגענו בזמינות של השרתים שלנו? ברגע שחומרת המחשב המשותף קורסת - יושבתו מיידית כל ה VMs שרצים עליה!!

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

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

אתחול של VM הוא מהיר מאתחול של שרת פיסי, מה שמפחית את ה Mean Time To Recover (בקיצור: MTTR) של המערכת. האתחולים המהירים (בעת תקלות תוכנה) מתקזזים עם תקלות החומרה (הנדירות יחסית) של חומרת השרת המשותף - כך שבדרך כלל, וירטואליזציה דווקא מוסיפה לזמינות של כלל המערכת.

הרצה של תוכנה על וירטואליזציה מספקת יתרונות נוספים:
  • היכולת "להרים" שרתים בקלות מפשטת את עבודת ה IT.
  • בזמן שדרוג, ניתן בקלות להרים VM עם גרסה חדשה יותר של התוכנה, במקביל לגרסה הישנה. ניתן להפעיל את המערכות זמן-מה במקביל ו"לכבות" את הגרסה הישנה רק לאחר שנצפתה עבודה תקינה של הגרסה החדשה.
  • שיפור הזמינות ע"י חלוקה: אם ניקח מערכת שהיא easily scalable, למשל שרת ווב, ובמקום VM אחד נציב שני VMs שלו על אותה מכונה פיסית - נקבל זמינות משופרת. אם VM אחד קרס בשל בעיית תוכנה, ה VM השני יכול להמשיך ולספק שירות. כל זאת - עם אותה החומרה (אבל קצת יותר זיכרון).
  • Checkpoints: טכנולוגיית הוירטואליזציה מאפשרת לקחת snapshot של VM מסוים, ואז לשמור את ההעתק בצד - או לשכפל אותו ל VM נוסף. יכולות אלו מקלות מאוד על עבודת ה IT. יכולות אלו מקלות מאוד גם על פיתוח תוכנה: לבדוק את התוכנה על מערכות הפעלה שונות בגרסאות שונות, או מפתח אחד שמתקין את הגרסה החדשה ביותר - ומשכפל אותה שתהיה זמינה לכל חבריו לצוות.



איך וירטואליזציה עובדת

הסביבה שמריצה וירטואליזציה של מכונה נקראת Virtual Machine Monitor (בקיצור: VMM) או Hypervisor. מקור השם Hypervisor טמון בהרשאות מערכת ההפעלה שניתנות לה: בעוד ההרשאות הגבוהות במערכת ההפעלה שייכות למשתמש העל (supervisor) - ל VMM נדרשו הרשאות גבוהות אפילו יותר, דרגה מעל ה supervisor, כלומר hypervisor.

הציפייה מ Hypervisor היא שהוא ימלא 3 דרישות עיקריות:
  1. Fidelity - התוכנה תרוץ על ה VM בדיוק כפי שהיא רצה על מערכת הפעלה שמותקנת ישירות על החומרה.
  2. Safety - תוכנה שרצה על VM תהיה מבודדת מתוכנה שרצה על VM אחר על אותו מחשב פיסי. פעולות שיעשה VM אחד (ניהול משאבים של מערכת ההפעלה, למשל) - לא יפגע בפעילות התקינה של ה VM השני.
  3. Efficiency - התוכנה על ה VM לא תרוץ "הרבה יותר לאט" מאשר על הרצה ישירות על החומרה הפיסית. 

מקורה של הגדרה זו היא במסמך שפרסמו עוד ב 1974 Popek ו Goldberg - חוקרים אמריקאים שהיו חלוצים בנושא הוירטואליזציה. הם גם הגדירו את התנאים שמאפשרים וירטואליזציה. בגדול הם הגדירו 2 קבוצות של פקודות המעבד (instructions):
  • sensitive - פקודות שמבצעיות פעולות IO.
  • privileged - פקודות שיגרמו ל trap אם נקראו ב user mode.
כידוע לכם (אני מניח), למעבדים יש 2 מצבי עבודה: user mode ו kernel mode. ה user mode נועד לתוכנות שרצות על מערכת ההפעלה (ולחלקים של מערכת ההפעלה) וה kernel mode נועד ל kernel של מערכת ההפעלה ורק בו ניתן לגשת ל I/O או לזיכרון ישירות. לכל mode יש סט פקודות זמין מעט שונה. אם פעולה של kernel mode נקראת ב user mode מתרחש אירוע בשם trap שגורם למעבד לעבור מצב ל kernel mode ואז להפעיל את הפקודה המבוקשת. מנגנון זה מאפשר לתוכנה לרוץ באופן ישיר על המעבד, בלי מעורבות של מערכת ההפעלה, ועדיין למערכת ההפעלה - לשלוט על כל הגישות לחומרה.


Popek ו Goldberg הראו ש Fidelity בוירטואליזציה יתרחש רק כאשר הפקודות שהן sensitive הם subset של הפקודות שהן privileged (מצב שלא היה קיים במעבדי אינטל - נושא עליו נדבר בהמשך).

דרך פשוטה ראשונה למשמש hypervisor היא כ interpreter שיפרשן כל פקודת שפת-מכונה של הקוד שרץ, ויחליט מה "בטוח" ולשלוח למעבד / מערכת ההפעלה - ובמה הוא רוצה להתערב ולשנות אותו. למשל: פקודת INC (כלומר: Increment) היא בטוחה, פקודה להשבתה של interrupt מסוים מהחומרה - היא לא, כי ייתכן שה interrupt הזה נועד ל VM אחר. בעזרת interpreter נוכל להשיג את דרישות הבטיחות והבידוד - אבל הביצועים יהיו גרועים.

דרך יותר מעשית, והיא בעצם הדרך המקובלת היא להגדיר את ה Hypervisor כ"מערכת ההפעלה של מערכת ההפעלה":

הדוגמה הספציפית היא ל type1 hypervisors אבל העקרונות נכונים גם עבור type 2 hypervisors עליהם נדבר בהמשך.

ה hypervisor "משתלט" על ה kernel mode של המעבד - כי עליו לתפוס את כל הגישות לחומרה, ומריץ את מערכת ההפעלה המתארחת (Guest OS) ב user mode. פנימית עושים הבחנה בין מערכת ההפעלה שזוכה ל virtual kernel mode (כלומר: מדמים לה שהיא רצה ב kernel mode - למרות שהיא לא) ול virtual user mode - מה שמערכת ההפעלה המתארחת מצפה שיהיה user mode.
הערה: במעבדי אינטל ספציפית יש 4 modes של ריצה שנקראים ring 0 (המקביל ל kernel mode) עד ring 3 (המקביל ל user mode). מימושים רבים של VMM מעל ארכיטקטורת אינטל פשוט משתמשים ב ring 1 בכדי לתאר את ה virtual kernel mode, כאשר virtual user model פשוט נותר ring 3. יש כאלו שמתארים את ה hypervisor כ ring -1 - אבל לא נכנס לפינה הזו בפוסט....

כאשר הקוד ב virtual kernel mode (שחושב שהוא ב kernel mode) מפעיל פקודה שהיא privileged אזי יש trap שמעביר את השליטה ל hypervisor.
כאשר הקוד ב virtual kernel mode מפעיל פקודה שהיא sensitive אבל לא privileged (כלומר: לא גורמת ל trap) אזי תהיה שגיאה וסביר שמערכת ההפעלה תקרוס. אאוץ!

מצב זה (בו יש פקודות sensitive שניגשות לחומרה, אך לא privileged - לא גורמות ל trap) היה קיים בכמה מארכיטקטורות המעבדים הזמינים בעולם, בניהן הארכיטקטורה הנפוצה ביותר בעולם - i386 של אינטל. אחד מהערכים של אינטל הוא תאימות לאחור (שנוכל על המעבד החדש להריץ אותן תוכנות שרצו על מעבדים ישנים) - מה שגרם למצב בו ארכיטקטורה זו שלא מתאימה לוירטואליזציה השתמרה במשך כמעט 30 שנה. ואיפה סביר יותר שתצמח טכנולוגיית הוירטואליזציה - על מחשבים פשוטים וזולים (אינטל) או מערכות מחשבי-ענק של IBM?

הבעיה נפתרה לבסוף בשנת 2005 כאשר אינטל, בשיתוף פעולה לא-שגרתי עם AMD, הוסיפו סט פקודות למעבד שפותר את המצב. באינטל מעבדים אלו מסומנים כ VT (כלומר: Virtualization Technology) וב AMD השם הוא AMD-V - אבל בעצם זה אותו הדבר.

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

הערה: אינטל עדיין מוכרת דגמים בודדים של מעבדים ללא VT - אני מניח שעבור מערכות בהן שינוי זה פוגע בתאימות לאחור.


מה עשו בעולם האינטל עד הופעת ה VT (ספציפית VT-x)?
חברת VMWare הציעה פתרון וירטואליזציה כבר בשנת 1999. הפתרון של VMWare סרק את קוד המכונה שנטען ל VM ושינה אותו כך שלא יקראו פקודות sensitive ב user space. אולי זה נעשה ע"י הרצת פקודה privileged תפלה קודם לכן - אולי בדרכים אחרות. פתרון נחשב פחות יעיל - אך הוא אפשר להריץ וירטואליזציה על מעבדי אינטל ללא VT (לא היו כאלה ב 1999).

חלק גדול מפתרונות הוירטואליזציה היום (VMWare, VirtualBox, KVM, וכו') יודעים לעבוד גם עם VT-x וגם בלי יכולת זו - ואז הם מבצעים fallback של שכתוב קוד המכונה למצב שמאפשר וירטואליזציה.

הפתרון לשכתב את קוד המכונה לאי-שימוש בפקודות sensitive נחשב (מסיבות הגיונית) לפוגע Efficiency של הקוד הרץ על ה VM.
אם תשאלו בפורום מקצועי את השאלה: "מה קורה אם אני מריץ את ה VMM שלי ללא VT-x", סביר שתשובה שתקבלו היא "אז ה VM יזחל כמו עגלה!".

שני חבר'ה מ VMWare הראו במאמר שפרסמו ב 2006 שמסקנה זו איננה כ"כ נכונה. לכתוב קוד המכונה לפקודות לא sensitive יש אמנם עלות, אך הוא מפחית את השימוש ב traps במעבד. אירועי ה trap במעבד גורמים ל context switch שמייתר חלק מה caches של המעבד ומשבש חלק ממנגנוני ה prediction, והפחתה שלהם - יכולה להאיץ את הריצה.

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

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


מקור: אינטל




סוגי Hypervisors


Goldberg, אותו הזכרנו קודם, הוא גם זה שהגדיר את ההבחנה בין Type 1 Hypervisors ל Type 2 Hypervisors.


Type 1 Hypervisors משמשים כמעין מערכת הפעלה והם התוכנה היחידה שרצה מעל החומרה / kernel mode. הם פשוטים ובד"כ אמינים יותר ממערכות ההפעלה[ב] (תכונה שנגזרת מכך יש להם הרבה פחות שורות קוד), והמפתחים שלהם יכולים לבצע אופטימיזציות שלא ניתן לעשות ב Type 2 Hypervisors. לרוב נראה אותם בסביבת השרת - היכן שאמינות ויעילות חשובות יותר

Type 2 Hypervisors הם תוכנה רגילה שרצה על מערכת הפעלה מסוימת (לינוקס, חלונות, וכו'), אולי במקביל לתוכנות אחרות, ועדיין מספקת הפשטה של החומרה למערכת הפעלה המתארחת. Hypervisors אלו תלויים (לטובה, ולעתים כמגבלה) בשירותים שזמינים במערכת ההפעלה המארחת (Host OS). כאשר אנו כמפתחים משתמשים בתוכנת וירטואליזציה כדי להריץ VM - זהו כנראה Type 2 Hypervisors.


למשל, בעולם של VMWare קל למפות את שני סוגי ה Hypervisors השונים:
  • ESX Server (ה hypervisor של חבילת vSphere) - הוא בעצם Type 1 Hypervisors.
  • VMWare Workstation / Player ו Fusion (למק) - הם בעצם Type 2 Hypervisors.
באופן דומה ניתן לומר שגם VirtualBox (של סאן, עכשיו אורקל) הוא Type 2 hypervisors ו Hyper-V של מייקורוספט נחשב כ Type 1 hypervisor (הוא משולב במערכת ההפעלה).

KVM (קיצור של Kernel based Virtual Machine), שהוא VMM בשימוש נרחב בעולם הלינוקס, הוא שנוי-במחלוקת מבחינת ההגדרה. הוא נארז כחבילה במערכת ההפעלה (כמו תוכנה hosted) ומקבל ממנה שירותים, אך יש לו גישה ישירה לחומרה (כמו type 1 hypervisor) - וכנראה שהוא נהנה מיתרונות דומים. ההגדרה, כמו הרבה הגדרות - היא טובה עד נקודה מסוימת.


Paravirtualization

עוד סוג של Hypervisors שקיימים הוא Hypervisors של Paravirtualization ("מעבר-לוירטואליזציה"). סוג זה של Hypervisors מנסה לשפר את ה Efficiency של הרצת ה VM, על חשבון מעט מה Fidelity. הרעיון הוא שהתוכנה שרצה על ה VM תהיה מודעת לכך שהיא שרצה בוירטואליזציה. ידע זה יתורגם לכמה קריאות API (נקראות Hypercalls) שבהן היא תשתמש במקרים מסוימים - שיאפשרו תהליך יעיל יותר של ההרצה. לרוב, מי שמודע לכך שהוא מתארח על סביבת ה Paravirtualization הוא מערכת ההפעלה המתארחת (ולא התוכנה שרצה עליה) והיא משתמש ב hypercalls לפעולות כמו עדכון הזיכרון הוירטואלי - פעולות שיכולות להיות פשוטות ומהירות יותר במידה והן נעשות בתיאום עם ה hypervisor.

 עוד נושא שמנסים להתמודד איתו ב Paravirtualization הוא העניין של "זמן אמיתי". מערכת ההפעלה המתארחת חושבת שהיא רצה על החומרה, ולא מודעת לכך שהיא משתפת את המעבד / I/O עם מערכות הפעלה אחרות - מה שגורם לפער בתפיסת הזמן (time) שלה. אם היא מסנכרת את תפיסת הזמן שלה בעזרת ה API (היעיל) של ה Paravirtualization Hypervisor - בעיה זו יכולה להיפתר.

Hypervisor ידוע שעובד ב Paravirtualization הוא Xen של חברת Citrix, הזמין גם בגרסה חינמית (אך ללא עדכונים אוטומטיים).




מקור: VMWare




Operating System-level virtualization


בנוסף לנושא ה Efficiency של ה VM, שתמיד נמוך מהרצה ישירה על החומרה, עניין שמתסכל את המשתמשים בוירטואליזציה הוא נושא ניצולת המשאבים. הבעיה לא גדולה אם אני מריץ VM אחד על המחשב הפיסי, אך מה אם אני מריץ עשרה?
נאמר שאני מריץ 10 VMs של לינוקס בגרסה זהה - זה אומר שכל השירותים של מערכת ההפעלה רצים 10 פעמים, הקוד שלהם נטען לזיכרון 10 פעמים, ומבני הנתונים שהם מנהלים - מנוהלים 10 פעמים. זהו מחיר ה isolation בין ה VMs - וזה מחיר יקר.

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

את הניסיונות לפתור את בעיית המשאבים - מנסים לפתור ה Linux Containers: להיות משהו יותר רזה מ VMM, אך יותר מקיף מניהול תהליכים במערכת ההפעלה, שה isolation שלהם מוגבל, וחלוקת המשאבים (למשל priority של תהליך) - לא מדויקת.

המסע ל Linux Containers התחיל במנגנון בשם chroot שהוצג על Unix7 בשנת 1979 (כבר אמרנו בפתיחה שוירטואליזציה היא לא דבר חדש). chroot יצר סביבת ריצה מעט שונה לכל תהליך - והתמקד בשיקולי אבטחה בין תהליכים. הוא בעצם שינה את ה root folder של כל תהליך כך שיראה רק אותו שלו של התיקיות, ולא יוכל להשפיע על תהליכים אחרים (ע"י גישה לקבצים שלהם, למשל). הסביבה שנוצרה לתהליך נקראה chroot jail, שם שליווה עוד פתרונות דומים אחרים (למשל FreeBSD Jail - "כלא BSD החופשי" :) )

עם השנים, היכולות התפתחו, והמיצוב נעשה ידידותי יותר: לא עוד jail אלא container.
מערכת ההפעלה לינוקס פיתחה יכולות ברמת הקרנל בכדי לתמוך באותם containers: בהתחלה cgroups (אריזת כמה תהליכים לקבוצה והקצאת משאבים מבוקרת לקבוצה) ולאחרונה LXC (קיצור של LinuX Containers, מבוסס על cgroups).

ה containers לא מקבלים את רמת ה isolation של VM ("מערכת הפעלה שלמה בשבילי"): הם משתפים את מערכת ההפעלה, הגרסה שלה, הדרייברים שלה עם שאר התהליכים שרצים. אבל הם מקבלים מרחב זיכרון, רשת, ודיסק משלהם וכן מרחב הגדרות של מערכת ההפעלה משלהם (עד כמה שאפשר. נקודה חשובה ליציבות). כמו כן יש הקצאה שוויונית יותר של המשאבים בין ה containers השונים.

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

תמורת פשרות הללו מקבלים Efficiency כמעט של מערכת ללא וירטואליזציה בכלל, וניצולת משאבים טובה הרבה יותר (דיסק, זיכרון, וכו') מכיוון שרצה רק מערכת הפעלה אחת. ה mitigation לקריסת מערכת ההפעלה הוא בד"כ להריץ על containers יישומים ב cluster על גבי כמה מחשבים פיסיים שונים, או להריץ תהליכים שה availability שלהם הוא לא קריטי.

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









Docker


LXC הוא בסיס טוב ל"וירטואליזציה רזה", אך הוא עדיין בסיסי לשימוש. מעליו צמחו פתרונות שונים לניהול workflows וניהול שוטף של העבודה. ללא ספק, הכלי שצמח הכי מהר בתחום זה הוא Docker. אם אתם עובדים בסביבת ענן / DevOps ולא שמעתם את השם הזה עד עכשיו - תבדקו את המקורות מהם אתם מתעדכנים.

הקהילה (development community) של Docker היא מהמתפתחות במהירות הגבוהה ביותר בעולם הקוד הפתוח. בעת כתיבת הפוסט הפרויקט הוא בן משנה וחצי (החל במרס 2013), אך שימו לב לפופולריות שלו ב Github:



כ Benchmark (הוגן, אני מקווה) בחרתי ב Chef - פרויקט באותו הדומיין פחות או יותר (אוטומציה של ניהול תצורה), פופולרי למדי, ושקיים כבר כ 5 שנים:




אין דברים כאלו!

ההתלהבות מ Docker היא קצת מעבר ל Github עצמו:
  • האגדה מספרת, שחברי הפרויקט החלו לעבוד ב Github בצורה ציבורית - ופתאום שמו לב שיש להם עשרות תורמים שהם לא מכירים (לרוב פרויקטי ה Open Source יש תורם משמעותי אחד).
  • יש כבר סטארט-אפים שסובבים סביב Docker: רשימת 10 הסטארט-אפים הטובים ביותר הבנויים מסביב ל Docker.
  • יש כבר כמה חברות שהחליטו לאמץ אותו כרכיב מרכזי בתשתית שלהן (למשל eBay, Rackspace, או Cloudflare).

Docker קרוי על שם מכולות ההובלה המשמשות (גם/בעיקר) להובלה ימית. מספרים שהמצאת המכולה הסטדנרטית שינתה את ההובלה הימית מקצה לקצה: במקום "התמחות" בתובלה של חפצים מסוג מסוים - כמעט כולם מתמחים בהכל ע"י כך שהם מעבירים רק מכולות. המכולות מכתיבות את מבנה הספינות, את מבנה הנמלים את גודל המשאיות וכו'. הסטנדרט הזה אולי קצת מגביל פה ושם - אבל בעיקר מאוד מועיל: מאז שהופיעו המכולות מחיר ההובלה צנח ותהליכי ההובלה נעשו פשוטים יותר.

Docker מאפשר:
  • לבנות containers של הקוד שלכם מתוך סקריפט.
  • לנהל את הגרסאות השונות של ה containers ב repositories שונים.
  • לבצע deploy קל container על שרת שהוגדר.
  • להעביר בקלות container רץ משרת אחד לשרת אחר (עבוד Continuous Delivery, פיזור עומסים, או סתם כדי להעביר אותו לסביבה מעודכנת יותר).
Docker עוזר לנהל כמה מהמגבלות של Linux Containers ולהפוך אותן למגבלות קטנות יותר. סביבות ניהול משוכללות כבר קיימות לפתרונות וירטואליזציה (למשל VMWare vSphere), אך לא כ"כ ל Linux Containers - ובחינם. Docker הוא הבסיס לכזו סביבה, ויש לא מעט סטארט-אפים שמנסים להפוך אותו לסביבת ניהול שלמה. כפי שאמרנו Docker מתבסס היום על LXC, אבל בפרויקט כבר מדברים על אפשור היכולות שלו עבור סביבות וירטואליזציה שונות כגון Xen, KVM, או אפילו Hyper-V (של מייקרוסופט).

הציפיות מ Docker הן דומות לאלו שהיינו מצפים היו ממכולות התובלה: לשנות את פני ניהול ה Data Center בצורה שתהפוך אותו לדבר שונה ממה שאנו מכירים אותו היום.







סיכום


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

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

למרות הדימוי ה"בשל" שיש לטכנולוגיות הוירטואליזציה - יש גם הרבה חידושים. התפר בין וירטואליזציה ל Operations הולך ומתטשטש ויש פתרונות שונים - לצרכים שונים.
היום בו יהיה VM אחד דומיננטי בו כולם ישתמשו (למשל VMWare) - נראה רחוק מתמיד.

עוד נושא קרוב, שלא דיברנו עליו בכלל הוא SDN - קיצור של Software Defined Network, תחום שעוסק בוירטואליזציה ואוטומציה של הניהול (המורכב) של הרשת. נשאיר משהו לפוסטים עתידיים.


שיהיה בהצלחה!





---


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

[ב] מאמר מפורסם בנושא הוא "?Are Virtual Machine Monitors Microkernels Done Right"