ארכיטקטורות ללא שרת (Serverless Architectures) – מה זה השטויות האלה?!

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

\"עכשיו תעשה לי את זה בלי שרת\" – מבקש המראיין.
ווב, בלי שרת? כלומר… Rich Client שלא מתקשר עם אף אחד?

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

מאז שנות ה-80, מודל ה Client-Server הוא המודל העיקרי של מערכות תוכנה, והוא עובד טוב. יש טרנדים: פעם לקוח רזה, ופעם לקוח שמן. פעם שרת מרכזי, ופעם שרת-רזה. אבל בכל זאת, ובמיוחד מאז עליית האינטרנט בשנות ה-2000 – אין כמעט מערכות שאנו משתמשים בהן שלא מחוברות לאיזשהו שרת (חוץ מכמה אפליקציות אופיס, Photoshop, או משחקים – וגם זה משתנה).

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

הרי קשה להתעלם מהבאזז המוזר הזה של \"Serverless Architectures\", באזז שכולל Frameworks, ספרים, ואפילו Conference שמוקדש לנושא.

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

הכרזה של ServerlessConf בניו-יורק

אז מה בעצם הכוונה ב \"Serverless\"?

כמו באזזים שונים שנתקלתי בהם בעולם התוכנה לאורך השנים (\"SOA\", \"MVC\", או \"Big Data\"), חוסר בהירות או אחידות בהבנת העקרונות הבסיסיים מאחורי הבאזז – לא מונעים מהבאזז לפרוח (אולי אפילו להיפך). זה קצת כמו הברקזיט: קודם מצביעים – ואז הולכים להבין במה מדובר 😉

את באזז ה Serverless ניתן לקשר לשלושה כיוונים עיקריים:

BaaS (קיצור של Backend as a Service) – שירות המאפשר למפתחי צד-לקוח (בעיקר מובייל, ולכן לעתים נקרא גם MBaaS) לבצע bootstrapping[א] מהיר ללא הצורך בידע והשקעה בצד השרת.
שירותים כמו parse.com (שנקנתה ע\"י פייסבוק ואח\"כ נסגרה), Firebase, או Kinvey הפכו פופולריים בעולם הסטארטאפים, וקיימים גם פתרונות פופלארים בקהילות הסגורות של עולם ה Enterprise (יבמ, אוקרל, סאפ) שבוודאי יהיו פחות מוכרים לאיש התוכנה הממוצע.

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

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

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

FaaS (קיצור של Functions as a Service) היא הגל השני של ה Serverless Architectures, שעלה לכותרות בעיקר בעקבות ההצגה של שירות AWS Lambda. למרות שהשירות שוחרר בגרסתו הראשונית עם מגבלות רבות, הוא הגיע משחקן מוכר ומוערך מאוד (אמזון), עם מחיר כניסה אפסי (אפשר להתנסות בו במחיר של סנטים), ובמרחק נגיעה – כי למאות אלפי (?) מתכנתים יש כרטיס אשראי כבר מוזן באמזון, והם יכולים להפעיל את השירות במרחק של קליק.

הפתרון, בגדול, מאפשר לכתוב ולעשות deploy לפונקציה בודדות – שתופעל כתגובה לקריאה ל endpoint (נקראים: \"event sources\") שנגדיר.
תפעול הפונקציות הללו (ניהול עומס, monitoring, ו High Availability) מנוהל ע\"י אמזון. רק מעדכנים את קוד הפונקציה – ואמזון דואגת לשאר.
בעצם FaaS הוא סוג של PaaS (כלומר: Platform as a Service, סליחה על השימוש התכוף בבאזזים) ברזולוציה קטנה הרבה יותר: במקום אפליקציה – פונקציה.

מאז הצגת AWS Lambda הזדרזו המתחרים להציג שירותים מקבילים, והיום יש לנו גם את Google Cloud Functions (עדיין באלפא, בעת כתיבת פוסט זה), את Azure Functions (גם הוא חדש), ואת OpenWhisk של יבמ (שרצה על פלטפורמת Bluemix של יבמ, פלטפורמה מוכרת בכנסים – וקצת פחות מפתרונות בפרודקשיין).

במקביל לענקיות הענן, ישנם גם מפתרונות של שחקנים קטנים, למשל:StackHut או WebTask.

האם ב FaaS אין שרת? – יש קוד צד-שרת, אבל בעצם מדובר בסט של פונקציות עצמאיות המנוהלות ע\"י מישהו אחר. יש צד-שרת, למרות שאין \"שרת\".
האם זו נישה? – כרגע כן. הרבה משחקים באופציה החדשה, מתלהבים (\"יו! פאקינג אינסוף Scalability!!\"), אבל גם מתפכחים (\"אהה.. אבל ה DB הוא צוואר הבקבוק של ה scale\" / \"קצת נהיה בלאגן\" / \"זה יוצא דווקא דיי יקר…\").
האם זו גישה חדשנית או אפילו מהפכנית? – אולי. נהיה חכמים יותר עוד שנתיים – שלוש. עדיין יש פה גישה חדשה שמאתגרת הרבה מאוד ממה שהתרגלנו אליו עד עכשיו בעולם צד-השרת.

תת-וריאציה (מעט משונה) של FaaS היא DBFaaS, הגישה הזו גורסת שלעתים קרובות אנו זקוקים ב FaaS לפנוקציות שמבצעות עיבוד קל על נתונים. היכן יותר יעיל לשים את הפונקציות הללו – אם לא ב Database עצמו?
לחברת SAP יש מוצר בשם HANA, בסיס נתונים in-memory, שמאפשר ממשק וובי ישיר ל stored procedures שלו.
גישה זו שוברת כמעט כל מוסכמה של Layered Architecture או MVC, ומציבה דאגות רבות (Scalability? אבטחה? יכולת debugging ותהליכי תוכנה נכונים?). אני עדיין לא מצאתי איזון בריא לגישה הזו – אך אין ספק שהיא מערערת מוסכמות וגורמת לחשיבה מחודשת של הדברים. למה בעצם לא??

טרנפורמציה של ארכיטקטורת Client-Server לארכיטקטורת Serverless. מקור: Bliki

Serverless Web Site (אין קיצור מגניב)

תצורה אחרונה, וקצת פחות מהותית מהאחרות אליה מתייחסים כ Serverless Architecture היא לארח אתר אינטרנט (לרוב עם פונקציונליות מוגבלת, ובעיקר חוסר-תקשורת בין המשתמשים השונים) כ Static Content, ובניית כל הפונקציונליות ב JavaScript.
את קובצי ה HTML/CSS/JavaScript מארחים בשירות אכסון כמו S3 או אפילו עדיף – CDN.

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

כמה שהגישות השונות שהצגתי הן שונות זו מזו – יש ביניהן סינרגיה.

כאשר אנו משתמשים ב BaaS, תחת היכולות הגנריות שמציע השירות הספציפי – מה יותר טבעי מלהוסיף קצת custom server functionality כ FaaS?

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

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

מקור: אמזון. לטעמי השימוש כאן במונח \"Microservice\" הוא לא ממש מדויק.
אם היו גם מציינים גם Big Data, דוקר, ו IoT – זה היה כבר יותר הגיוני 🙂

אז מה הם באמת התכונות העיקריות של ארכיטקטורה \"ללא-שרת\" (קרי: מבוססת FaaS)?

אפשר לייחס ל Serverless Applications את התכונות הבאות:

  • התבססות במידת האפשר על שירותי צד-שלישי.
  • ה Flows העיקריים של האפליקציה מנוהלים בצד-הלקוח. צד השרת מספק בעיקר \"פונקציות\".
  • בניגוד לשרת שחי לאורך זמן, וטיפל בבקשות שונות – ב Serverless Architectures המופע של צד-השרת חי לאורך טיפול בבקשה. יכולים להיות אלפים כאלו שמופעלים ונדומים בשנייה.
    • זו תכונה טכנית יחסית, שעשויה להשתנות. ייתכן והספקים יתחילו לספק הנחות למי שמבטיח כמות מסוימת של שימוש בשעה – והדרך להוזיל עלויות תהיה כן להחזיק כמות מסוימת של instances קבועים.
    • יתרונות נוספים של instances קבועים הם cache \"חם\" (ברמות השונות) וביטול / קיצור ה initialization latency.
  • ארכיטקטורות Serverless לוקחות את רעיון ה Continuous Deployment לאקסטרים חדש: כעת ניתן, בכל רגע, לבצע דיפלוי ברזולוציה של פונקציה בודדת.
יתרונות:
  • חסכון בעלויות, כי משלמים רק על מה שרץ – במיוחד כאשר יש traffic דליל. בסקייל בינוני ומעלה – זה יותר יקר.
  • יותר אופרציה מנוהלת ע\"י ספק השירותים, או קצת בהקצנה: noOps#. רעיון ה Platform as a Service (בו כמעט כל היבטי ניהול אפליקציות מבוצע ע\"י הספק) לא הצליח כ\"כ בפועל, אך יש סיכוי שמודל ה FaaS יצליח יותר.
  • כאשר כל פונקציה (עם מאפייני הביצועים הייחודיים שלה) היא מבודדת – קל יותר לעשות Scaling. טעות נפוצה היא ש FaaS הוא \"infinitely scalable\". כאשר יש לפונקציה state משותף כזה או אחר – צווארי הבקבוק של ה scalability יהיו שם – כפי שהיה תמיד.
  • אפשרות לקרב את הפונקציה למשאב אחר, למשל: קרוב מאוד לשירות צד-שלישי ולבצע חישובים שם, קרוב לנתונים, או אולי קרוב ללקוחות (למשל: לשים פונקציות שירוצות אצל ספק ה CDN וכך יספקו תשובות מאוד מהירות למשתמשי הקצה שלי, בכל רחבי העולם).
חסרונות:
  • חלוקה של מערכת להרבה פונקציות קטנות דיי מהר הופכת לאתגר תפעולי מצד המתכנתים. רבים מהמימושים המוצלחים של FaaS כרגע – מבוססים על פונקציות מעטות.
  • חלוקת המערכת להרבה פונקציות קטנות עלולה ליצור קשיים בהשגת אמינות גבוהה: הרשת יכולה לשבש קריאות בין פונקציות שונות – ואם אנו זקוקים ל\"אפס פספוסים\", אנו נצטרך להתגונן בפני כשל של הרבה מאוד נקודות אינטגרציה.
  • Lock-In ל Vendor המספק לכם את השירותים. אולי הפונקציות עצמן מבודדות (isolated), אך סביר שהן משתמשות ב infrastructure נוסף (הרשאות, API Gateway, אכסון נתונים, וכו\') שכובל אתכם לספק הספציפי.
  • כאשר כל פונקציה רצה בפני עצמה בשרת צד-שלישי, ולא ניתן להריץ את הקוד לוקאלית – הפיתוח נעשה מורכב יותר. 
    • לא יפתיע אותי אם נראה בקרוב יותר ויותר אמולטורים שמאפשרים להריץ את פתרונות ה FaaS (בצורה פחות יעילה / אמינה – רק לצורך פיתוח) על המחשב המקומי.
  • לפחות כרגע, לפתרונות כמו AWS Lambda יש Initialization latency לפונקציה – כלומר: אתחול הפונקציה מוסיף לזמני התגובה כ 100-600 מילישניות (ע\"פ דיווחים שונים). זה בסדר ל Event Processing, אבל קצת פחות טוב ל UI או מערכות semi-realtime.

    איזה סוג של מערכות אם כן, מתאימות יותר ל Serverless Architectures?

    • UI-Centric Apps – אפליקציות בהן חווית המשתמש היא המרכזית, והצרכים מצד השרת הם מצומצמים. אלו יהיו בעיקר אפליקציות מובייל – אך לעתים גם מערכות ווב.
    • Message-Driven Systems – מערכות שעיקר עיסוקן הוא טיפול באירועים, למשל: טיפול בטרנזקציות בנקאיות, איתור Fraud, או מערכת שמחליטה איזו מודעה להתאים למשתמש. מערכות אלו ניתן לפרק בקלות יחסית לסדרה של פונקציות, כאשר יש הגיון לשפר כל פונקציה בנפרד: הן מבחינת ביצועי תוכנה = לרוץ מהר יותר, והן מבחינת ביצועים עסקיים = לתת תשובה קצת יותר מדויקת.
      • אם המבנה הלוגיקה העסקית הוא של Pipes and Filters – מבנה ועקרונות של Serverless Architectures עשויים בהחלט להיות רלוונטיים.
      • באזז נוסף שמתקשר ל Message-Driver Systems ו FaaS הוא IoT (קיצור של Internet of Things): אירועים שמגיעים מהמון מכשירים קטנים.
    • חיזוק לנאמר לעיל: מערכות בהן אין (או כמעט ואין) State בצד השרת.
      • בשפה של תכנות פונקציונלי: הפונקציות של FaaS הן Pure Functions.
    • (קצת תיאורטי) יש טיעון שמערכות שחוות spikes גדולים מתאימות ל Serverless Architecture בגלל הציפיה לתשלום ע\"פ גרנולריות מדויקת של שימוש, ויכולת Scalability גבוהה כאשר הפונקציות הן stateless.
      • כאשר AMI של אמזון (שנבנה בצורה המתאימה) יכול לעלות ולהיכנס לשימוש בטווח של דקה או שתיים – רוב ה spikes יכולים להיות מטופלים בצורה סבירה עם autoscaling. קשה לי להאמין שהעלויות של FaaS יוכלו להתחרות בעלויות של ניהול התשתית בעצמנו (IaaS) – כאשר מדובר ב Scale גבוה. אין ארוחות חינם.

    לגבי העלויות ארצה לציין זאת במפורש: יש אינסוף אזכורים לכמה AWS Lambda עשויה זולה יותר מ EC2. שמעתי לא פעם את המספר \"80% חסכון!\". זה סיפור טוב. כשצוללים לפרטים, ניתן לראות סיפורים על חסכון משמעותי – כאשר יש 3 קריאות ביום (מול שרת t2.micro).

    יותר קשה למצוא ניתוחים של עלויות AWS Lambda ב scale גבוה. כל הניתוחים הללו שראיתי (הנה דוגמה) מראים מחיר גבוה יותר בשימוש ב Lambda מאשר בשימוש ב EC2.

    סיכום

    \"כמה זמן יעבור עד ש Serverless Architectures יהיו הסטנדרט?\" – היא שאלה שכבר שמעתי.
    \"כמו שהענן הולך להעלים את תצורות ה On-Premises… הרי Serverless יעלימו את ה Client-Server\"

    האמת – שאני לא יודע.
    ייתכן וזה באזז שיחלוף, וייתכן שלגישת ה Serverless Architectures תהיה השפעה רבה על עיצוב מערכות מכאן ואילך.

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

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

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

    ב FaaS לוקחים חלקים מאוד ספציפיים מהמערכת (או מהמיקרו-שירות), בד\"כ חלקים פשוטים, ולהוציא אותם החוצה. המוטיבציה היא מכלול של שיקולים שונים כמו: ניהול ע\"י צד שלישי, Scalability גבוה, קרבה למשאבי מחשוב (למשל: לשים פונקציות מסויימות על ה CDN שלי כך שיהיה קרוב למשתמשים ויספק תשובה במילי-שניות ספורות), וכו.
    חלוקה שכזו עובדת טוב על פונקציות שיש להן מינימום תלויות, וכמה שפחות state – או לפחות: shared state.

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

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

    [א] קרי – להעמיד מוצר ראשוני / התחלתי

    Monitoring: מבוא ל Graphite ושימוש ב Time-Series

    Graphite היא מערכת Open Source פופולארית למדי לניטור (Monitoring).
    בצורה המקוצרת ביותר, היא מבצעת 2 פעולות בסיסיות:

    • אוספת מספרים שמשתנים לאורך זמן (להלן \"time-series\").
    • מציגה אותם כגרף.
    המערכת מבוססת על עקרונות פשוטים למדי, ומסוגלת לטפל במליוני data points בשנייה.
    Graphite זכתה לאימוץ נרחב בתעשייה, ככלי Monitoring חשוב. רבים משתמשים בה (ומספרים על זה): Github, Etsy, אובר, Electronic Arts, ועוד.

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

     מצד שני – צצו גם תלונות שונות על המערכת:

    • ניהול הנתונים כקבצים אינו יעיל כאשר מתשאלים הרבה מטריקות (metrics) במקביל. בהמשך נראה שזה מצב כמעט ובלתי נמנע…
    • ה UI הוא לא כ\"כ יפה…
    • יש פונקציונליות חסרה, למשל: aggregation של נתונים, alerts, וגילוי אנומליות…
    • ההתקנה של Graphite היא לא פשוטה (הרבה תלויות), והתפעול השוטף שלה – גם עשוי להיות לא כ\"כ פשוט.
    מכיוון ש Graphite היא מערכת המורכבת ממודולים נפרדים עם APIs מוגדרים היטב – הצרכנים שהתלוננו פשוט החליפו חלקים שונים במערכת. בלי לשם לב, נוצרה אסופה גדולה של מודולים להחלפה, כאשר ה APIs שהגדירה Graphite  – הפכו לסוג של \"סטנדרט\" בתעשייה, אליו מתממשקים כלים רבים.

    כיום כבר ניתן לראות הרבה תצורות בהן החליפו חלק מהרכיבים של ה \"Graphite Stack\", ואפילו תצורות ללא אף אחד מהרכיבים המקוריים. Graphite הוא עדיין אחד כלי ה Monitoring הנפוצים ביותר שקיימים.

    אם אתם קוראים אדוקים של הבלוג, אתם בוודאי יודעים שאני מאוד אוהב כלי Monitoring בשם New Relic- בעבר כתבתי עליו פוסט.

    מה הטעם להשתמש ב Graphite כאשר יש לנו כלי monitoring נהדר כמו New Relic?

    1. New Relic הוא כלי יקר [א], וייתכן שיש מערכות שלא משתלם לשלם עבורן את ה premium של New Relic.
    2. New Relic מגיש סט מאוד שימושי של מדדים וניתוחים, אבל לעתים אנו רוצים מדדים ש New Relic לא מספק.
      1. דוגמה קלאסית: מדדים עסקיים.
        בעולם של Gett: כמה הזמנות יש, כמה נהגים פנויים, כמה נוסעים שממתינים למונית כבר רבע שעה?
      2. ב New Relic קיימת פונקציונליות שדומה ל Graphite (עבור מערכות שמנוטרות ברישיון).
        New Relic מקשר את הנתונים בצורה קשיחה לאפליקציה, מה שעלול להקשות. אנחנו במקרה מסוים עזבנו אותו בנקודה זו לטובת Graphite, אם כי לא התאמצנו יותר מדי להשתמש בו. ייתכן ויש לזה פתרון.

    Graphana – ה Dashboard ה\"חם\" בעולם ה Graphite כיום.

    הארכיטקטורה של Graphite

    בצורה פשטנית משהו, ניתן לתאר את הארכיטקטורה של Graphite בצורה הבאה:

    • ניתן לזהות ב Graphite שלושה רכיבי-על מרכזיים: whisper, carbon ו graphite-web.
    • המערכת (Application) שולחת נתונים של מטריקות (metrics) שונות ל carbon מעל tcp (פורט ברירת-מחדל: 2003).
      • הפורמט בו מועברים הנתונים הוא מאוד פשוט: some metric name : some value : timestamp.
    • קרבון שומר את הנתונים בבסיס הנתונים whisper, בסיס נתונים שמבוסס על קבצים ודומה לכלי ישן, יחסית, שנקרא RRD [ב].
      • whisper מנהל קובץ נפרד לכל מטריקה, הוא למעשה סוג של Time Series Database (פרטים בהמשך).
    • Graphite-web יודע לקבל קריאת GET (בעזרת endpoint בשם render/) כשהפרמטרים על ה URL מתארים query על מטריקה או מספר מטריקות.
      • למשל: הפרמטר הבא סוכם את כמות ה logins היומית:
    target=summarize(my.metric.logins, \"1d\")
      • Graphite-web מרנדר PNG אותו הוא מגיש לדפדפן.
        הערה: זהו אלמנט של חוסר יעילות: היום קל יותר לקבל נתונים ולרנדר אותם ב javaScript – כך גם העבודה מתפזרת בין ה clients השונים.
    Graphite כתובה ב Python, כאשר carbon ממומש ע\"ג twisted (שהוא framework ל event-driven I/O) ו graphite-web כתוב ב django – ספריית MVC מפורסמת שדומה באופייה ל Rails.

    Time Series Databases (להלן TSDB)

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

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

    1. לדחוס את הנתונים בצורה יעילה יותר.
    2. איתור מגמות (trends), מחזורים (cyclical fluctuation), ועונתיות (seasonal fluctuation) בנתונים.
    3. לנתח חריגות בנתונים (אנומליות).
    4. לנסות לחזות את המשך הסדרה.
    5. להיות מסוגלים לחשב (בדיוק כזה או אחר) את ההסתברות להתנהגויות עתידיות של הסדרה. למשל: הסבירות לקטסטרופה עתידית.
    סדרות עתיות הן טובות לתאר מדדים של מזג אוויר, ונתונים כלכליים – מצד אחד, אך גם metrics של סביבת הפרודקשיין שלנו, וביצועים של מדדים עסקיים – מצד שני. ישנן טכניקות מתמטיות משמעותיות לניתוח נתונים של סדרות עתיות.

    מקור: Sabbir Rehman

    בסיסי נתונים רלציוניים (או KV/Document) מסוגלים בהחלט לנהל סדרות עתיות, במיוחד כאשר הם רצים על חומרה עם SSD (שמספקת ביצועים טובים בהרבה מדיסק מכאני לגישות אקראיות רבות).

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

    • ניצור טבלה לכל מדד (למשל: צריכת זכרון של שרת A, צריכת זכרון של שרת B, כמות פעולות IO של שרת A,… וכו\')
    • בכל טבלה יהיו שתי עמודות: זמן, וערך המדד.
    כאשר יש לנו *הרבה* נתונים (מה שקורה לעתים קרובות ב Monitoring), ניתן לבצע אחת מ-2 אופטימיזציות מקובלות:
    1. ליצור טבלה לא רק לכל מדד, אלא גם לכל מדד וטווח זמן – למשל מדד + תאריך (יום מסוים). כל יום יהיה טבלה חדשה.
      1. אם הטבלה מייצגת תאריך – אז שדה הזמן יכול עתה להיות מצומצם לשעה ביום (ברזולוציה הנדרשת: שניות או מילי-שניות, למשל), וכך לחסוך מקום רב של אכסון, בעיקר באינדקסים.
      2. התוצאה כמובן יכולה להיות שבמערכת יהיו לנו מאות או אלפי טבלאות שונות.
      3. לרוב מקובל לשמור את הערכים לטווח מוגדר (נאמר: 30 יום), ולמחוק טבלאות ישנות יותר.
    2. לצמצם את מספר השורות ע\"י אכסון של טווח ערכים בכל שורה. למשל: יש לנו הרבה מדידות בשנייה (או בדקה), ואנו הופכים את הסכמה של כל שורה להיות: זמן, כמות דגימות, ממוצע דגימות, פיזור דגימות, ערך מקסימום, ערך מינימום ו BLOB עם כל ערכי הדגימות הספציפיים ומרכיב הזמן המתאים (שניה או מילי-שניה).
      1. אם עבור הרוב הגדול של השאילתות הרזולוציה אליה צמצמנו את הנתונים (נאמר: דקה) היא מספיק טובה, אז רוב השאילתות יוכלו לרוץ על סיכמוי הביניים (למשל: \"ממוצע דגימות\" ו \"כמות דגימות\") – מה שירוץ הרבה יותר מהר.
        1. צמצום שמצדיק את הטרחה הוא לרוב צמצום של כמה עשרות או מאות ערכים שונים או יותר – לתוך שורה בודדת.
        2. אם נרצה לגשת לכל הערכים המדויקים (כנראה שנרצה לעשות זאת ברזולוציה קטנה, למשל – כמה דקות) – כל הנתונים עדיים שם. לא יצרנו איבוד מידע.

    דוגמה לדחיסה של נתוני סדרה עתית לרשומה / אובייקט יחיד. מקור: O\'Rielly, באדיבות MapR.

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

    • Splunk (מוצר proprietary)
      • משמש בעיקר לאינדוקס וניתוח נתונים (לא ממש monitoring), יותר נכון להשוות אותו ל ELK Stack מאשר ל Graphite Stack (למרות שהוא נחשב מוצר TSDB).
    • InfluxDB (כתוב ב Go, יכול לחבר אותו ל Storage Engines שונים כמו LevelDB או RockDB).
      • ניתן לאפיין אותו בפשטות התקנה / תפעול. הוא מתיימר להחליף את כל ה Graphite Stack בעתיד, ובנוסף הוא תומך במודל של time-events, שהוא רחב יותר ממודל ה time-series הקלאסי (מה שבא קצת על חשבון יעילות אכסון וביצועים). אולי שווה להקדיש לו פוסט בעתיד…
    • OpenTSDB (הממומש מעל Hadoop HBase)
      • ניתן לאפיין אותו ביכולת לטפל בכמויות גדולות מאוד של נתונים, ובמהירות. הוא מהיר בסדר גודל מ InfluxDB – כאשר כמות הנתונים גדולה מאוד.
    TSDB כוללים לרוב עוד כמה פונקציות מסביב למודל של סדרות עתיות:

    • downsampling – היכולת לשלוף נתונים ביעילות ברזולוציה קטנה יותר מזו שנשמרה (למשל: אנו שומרים מדד כל שניה, אך רוצים לשלוף את הערכים של פעם בחמש דקות).
    • ביצוע פעולות השוואה / חישוב בין סדרות עתיות שונות, או מקטעים שונים באותה סדרה עתית. למשל: מה ההבדל בין התנהגות המדד היום, להתנהגותו באותו היום – לפני שבוע?
    • אינדוקס הערכים ושליפה מהירה שלהם. למשל: שלוף את כל מקטעי הזמן בחודש האחרון בהם ה CPU utilization היה גבוה מ 70% – בצורה יעילה (ובהנחה שזה אירוע דיי נדיר).

    סה\"כ TSDBs כוללים tradeoff מאוד ברור: מודל נתונים פשוט ובסיסי של סדרות עתיות, עבורן ה TSDB יעיל בצורה לא-רגילה.

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

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

    סיכום

    בפוסט זה הכרנו את Graphite, כלי (או אולי Stack) טכנולוגיות פופולארי מאוד, בקוד פתוח – לניטור מערכות. הכח שלו – הוא ביכולת ה customization: ניתן להשתמש בו ל System Monitoring, ל Application Monitoring ואף ל Business Performance Monitoring. הבסיס שלו הוא דיי פשוט ויעיל – מה שתרם לפופולאריות הרבה שלו.

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

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

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

    —-

    [א] ע\"פ מקורות זרים: כ 100$ לחודש לשרת. ע\"פ מקורות זרים: ניתן להוריד את המחיר הנ\"ל לבערך חצי – אם אתם צרכנים כבדים (יש לכם מאות שרתים מנוטרים). מה המחיר לאלפים? לרוב אם יש לכם יותר מכמה מאות שרתים – אתם לא תשלמו כבר ל NR, אלא תשתמשו ב open source כמו nagios עם הרחבות שלכם…

    [ב] RRD הוא קיצור של Round Robin Database – על שם כך ששמר על קבצים בגודל קבוע בדיסק, ועשה שימוש חוזר בשטח שלהם.

    —-

    לינקים רלוונטיים

    רשימת כלי 3rd-party שעובדים עם Graphite:
    http://graphite.readthedocs.org/en/latest/tools.html

    הארכיטקטורה של Graphite, כפי שמתוארת ע\"י היוצר שלה, כריס דיוויס:
    http://aosabook.org/en/graphite.html
    תיאור טוב ממקור אחר:
    https://grey-boundary.io/the-architecture-of-clustering-graphite/

    דרכים למימוש סדרות עתיות על גבי בסיס נתונים רלציוני:
    https://academy.datastax.com/demos/getting-started-time-series-data-modeling
    http://dba.stackexchange.com/questions/7634/timeseries-sql-or-nosql

    ספר מבית O\'Reilly על TSDB, ו openTSDB בעיקר. ניתן לקבל בחינם במימון MapR (שמשקיעה ב OpenTSDB):
    https://www.mapr.com/time-series-databases-new-ways-store-and-access-data

    השוואה של 10 TSDBs:
    https://blog.outlyer.com/top10-open-source-time-series-databases

    Splunk vs. ELK
    https://riskfocus.com/splunk-vs-elk-part-1-cost/ (והמשכים…)

    HTTPS – חלק א': סקירה

    HTTPS הוא HTTP עם SSL (קיצור של Secure Sockets Layer). ה "S" ב HTTP משמעה "Secure".

    עד לפני מספר שנים, HTTPS היה פרוטוקול שהיה נפוץ בעיקר במערכות Enterprise, ו/או אתרים משעממים אחרים.
    דברים השתנו, ויותר ויותר אתרים משתמשים ב HTTPS בתור פרוטוקול ברירת המחדל שלהן: גוגל, טוויטר, פייסבוק ועוד. ע"פ סקר SSL Pulse (לינק עם נתונים גרפיים), בשנה האחרונה אחוז האתרים שעובדים ב HTTPS עלה מ 15%, ל 52%! ייתכן והסקר מעט מוטה – אך בהחלט יש כאן מגמה.

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

    1. HTTPS הוא "תואם" ל HTTP ואינו דורש (בתיאוריה) שינויי קוד בכדי לעבור אליו.
    2. החומרה נעשית חזקה יותר ויותר, והתקורה של עבודה ב HTTPS היא כבר לא-משמעותית*.
    3. מודעות גדלה לפרטיות ואבטחה ברשת.
    * מלבד מקרה חשוב אחד – עליו נדבר בהמשך.
    • האם המעבר ל HTTPS הוא "טוב ליהודים"?
    • מה HTTPS בעצם עושה? היכן הוא מגן והיכן – לא?
    • מה המשמעות, בשבילי המפתח, ובכלל – לעבוד עם HTTPS?

    על שאלות אלו, ואחרות – אנסה לענות בפוסט זה.

    Context: היכן פרוטוקול HTTPS "מתרחש"?

    הבהרה / היסטוריה: פרוטוקול ה SSL (קיצור של Secure Sockets Layer) הוגדר ע"י חברת Netscape עבור הדפדפן Netscape Navigator – שאיננו קיים עוד. הוא היה בגרסאות 1.0 עד 3.0, ואז הוא הועבר לגוף תקינה סטנדרטי ושמו שונה ל TLS (קיצור של Transport Layer Security). בשנת 1999 שוחרר TLS גרסה 1.0, הגרסה העדכנית של TLS היא 1.2 (שוחררה בשנת 2008).
    למרות שהשם "TLS" קיים כבר יותר מעשור, השם SSL דבק ועדיין מוכר יותר / משתמשים בו לעתים קרובות בהחלפה ל TLS. ישנו עוד ציוד רשת (בעיקר שרתים) שעדיין תומכים ב SSL או גרסאות ישנות של TLS – מה שמחייב את הדפדפנים לעבוד בגרסה ישנה יותר (ופחות מאובטחת) של הפרוטוקול.

    בסך הכל, TLS הוא פרוטוקול שרץ מעל TCP ומתחת ל HTTP (או פרוטוקולים אחרים ברמת ה"אפליקציה"), כך שבעקרון הוא לא משנה את אופן העבודה של HTTP:

    כדאי לציין שיש עוד פתרונות הצפנה ל HTTP כגון VPN או IPSec שהם ברמת פרוטוקול ה IP – אך הם מחוץ ל scope של דיון זה.

    אלו שירותים פרוטוקול HTTPS מספק?

    "הצפנה!" – נכון. אבל הצפנה של מה?

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

    • הצפנה של המידע העובר בין הלקוח לשרת – כדי שצד שלישי לא יוכל להאזין לתקשורת.
    • Authentication: זיהוי השרת ו (אולי גם) הלקוח – כדי שנדע, למשל, ש"הבנק" שלנו הוא באמת הבנק שלנו, ולא אתר מתחזה [ב].
    • וידוא שלמות ההודעה, בעזרת "חתימה דיגיטלית" – כדי להתמודד עם התקפות מסוג Man in the Middle.
    פרוטוקול TLS בפעולה בדפדפן כרום:
    ורוד – אני רואה שיש אימות שאני אכן מחובר לבנק הפועלים. לפני כל הכנסה של כרטיס אשראי – כדאי מאוד לוודא שהשרת מאומת ושמו נשמע הגיוני.
    תכלת – הממ…. 112-ביט הוא מפתח מעט חלש בימנו + חיבור 1.0 TLS הוא מעט לא מעודכן וחשוף להתקפות כגון BEAST (בהמשך)

    על מפתחות סימטריים וא-סימטריים (הצפנה)

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

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

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

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

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

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

    כדי להצפין ולפתוח מסרים ב RSA – זקוקים לשילוב של 2 המפתחות. ניתן לשלב אותם בשני האופנים הבאים:

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

    סה"כ מפתחות א-סימטריים היום הם באורך של 512 עד 2048 ביט – ודיי יקר למעבד לפענח אותם. דרך הפעולה של TLS הוא לבצע את התקשורת הראשונית בעזרת מפתח א-סימטרי (יקר להצפנה/פענוח). בערוץ המאובטח שנוצר – מעבירים מפתח סימטרי קצר יותר (קל להצפנה/פענוח) ושצריך פחות עבודת חישוב בו נשתמש מכאן והלאה. חתימה דיגיטלית יכולה לסייע לאמת את זהות המתקשרים (שרת / לקוח).

    האם פרוטוקול ה SSL/TLS הוא מוגן לחלוטין?

    לא.

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

    כרגע החוק בארה"ב (למיטב ידיעתי) מגביל את גודל המפתחות ל 256 ביט להצפנה סימטרית ול 2048 ביט להצפנה אי-סימטרית (במקרה שלנו: RSA).

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

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

    יש גם באגים בפרוטוקול ה SSL עצמו.
    התקפות מפורסמות אחרונות המבוססות על באגים אלו קרויות BEAST ו CRIME – וחלק גדול של משתמשי האינטרנט עדיין חשוף אליהן [ג]. חשוף, מכיוון ששרתי אינטרנט רבים הם לא מעודכנים ועדיין עובדים עם גרסאות ישנות של TLS או אפילו SSL (כלומר: גרסה ישנה הרבה יותר)
    .
    ע"פ שמועות, מומחי ה NSA "דחפו" באגים מתוחכמים לתוך התקן של TLS – כדי שהם יוכלו לנצל אותם בהמשך. יש פה הנחה, לא בהכרח נכונה, שהבאגים כ"כ מורכבים ופינתיים – שאף אחד לא ימצא אותם. ה NSA, בין היתר גם שילם ל RSA כדי שיחלישו את ההגנות שלהם.

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

    מה בהמשך?

    הפוסט מתארך ולכן אני מחלק אותו ל2 חלקים.
    בחלק א' סקרנו את הפונקציונליות הכללית של HTTPS (קרי TLS/SSL) וקישרנו אותו ל TCP/IP Stack שכולנו מכירים.
    בחלק ב' אנסה להתמקד ב HTTPS Authentication וה Certificates – צד חשוב מאוד בפרוטוקול ה HTTPS, ובהשפעה של HTTPS על מערכת / המתכנתים / Operations.
    שיהיה בהצלחה!

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

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

    [ג] לא צריך מאוד לדאוג – כי אלו התקפות מורכבות למדי ליישום. עדיין הייתי רוצה שכל שירות דואר אלקטרוני או אתר שמתעסק בכסף שלי, יעבוד עם TLS גרסה 1.2.