ארכיטקטורה של מערכת גמישה, עמידה וסקלבילית – חלק 3 (הנתונים – data)

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

מדריך זה הוא המשך ישיר לחלק הקודם המדבר על צד שרת (back-end), מומלץ לקרוא את חלק 2 לפני שממשיכים בחלק זה.

קבצים

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

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

מצד שני, אם צריך ממש לאמץ את המערכת, ייתכן ומערכות אלה לא ייתנו את המענה הטוב ביותר. היה לי מקרה שהיינו צריכים מערכת שיש לה המון בקשות של קבצים (I/O – קיצור של input output – כלומר מספר בקשות קריאה/כתיבה) אבל לא היתה צריכה נפח רחב של תעבודה (throughput), ולכן הפתרונות שצוינו לעיל לא עזרו. כיוון שהיה מדובר על קבצים שלא השתנו או גדלו בכמות הרבה – הקמנו שרת מקומי שהיה שרת קבצים מקומי, נתן שירותי NFS (שיתוף קבצים) לשרתים הקרובים, כאשר שאר הקבצים נשמרו ב-EFS. פתרון זה נתן לנו מהירות גדולה לקבצים עם הרבה בקשות אבל גם נפח בלתי מוגבל לשאר הקבצים.

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

מטמון (Cache)

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

אני אדגיש שוב – רצוי שיהיו כמה שפחות נקודות קריטיות (single points of failures). ככל שתבנו רכיב גיבוי על רכיב גיבוי – כך תהפכו את המערכת לאמינה יותר.

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

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

אבל מה שאני גיליתי שכדאי – זה לשלב ביניהם. שרת המטמון המרכזי צריך להיות מרכז העבודה, אבל חשוב לפזר ולחלק את העומס, במידת האפשר לשמור גם בשרת המקומי חלק מהמידע גם אם לטווח זמן קצר יותר. אבל זה לא מספיק, חשוב להעביר הודעה בין השרתים כאשר מידע כלשהו מתעדכן כדי שהשרתים ידעו לנקות/לעדכן את המידע שכבר לא עדכני אצלהם. אפשר לעשות את זה למשל בעזרת תכונת ה-Pub\Sub של Redis – כלומר אפשר שכל שרת "יירשם" (מבצע Sub – Subscribe) בשרת המטמון המרכזי, וכאשר מתבצע עדכון במידע של השרת – הוא שולח הודעה לכל שאר השרתים דרך ה-Redis (מבצע Pub – Publish), שאר השרתים מקבלים את ההודעה ויכולים לפעול בהתאם.

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

מסד נתונים (Database)

אנחנו נתמקד בשני הסוגים העיקריים והנפוצים של מסדי הנתונים היום. מסדי נתונים רלציוניים כמו Oracle, MS SQL Server, MySQL, Postgresql, ומסדי נתונים לא רלציוניים כמו MongoDB.

מסדי נתונים רלציוניים (Relational Database Management Systems)

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

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

בגזרה החינמית מבוססת קוד פתוח – MySQL צברה תאוצה אצל מפתחי אתרים פשוטים בגלל הקלות והנוחות שלה בשילוב שאין צורך לרכוש רישיון שימוש בה. Postgresql הראה גם כן יכולות מרשימות אך ככל הנראה היה מעט מורכב יותר למפתחים כיוון שנתח השוק שלו קטן יותר. במהלך השנים היו מספר גרסאות (forkים) שהתפתחו מתוך MySQL כמו percona או MariaDB (האמת שגרסה זו היא בעקבות סכסוך בין המפתחים המקוריים של MySQL לבין חברת Oracle שרכשה את חברת Sun שבזמנו היתה הבעלים של MySQL, מוזמנים לקרוא קצת על זה באינטרנט). גרסאות אלה נתנו מענה שונה לבעיות שונות של MySQL, אך כולן עדיין התבססו על הבסיס של MySQL.

הבעיה הבסיסית עם מסדי נתונים רלציוניים – היא שהן נבנו בתקופה בה המערכות היו יחסית פשוטות, מקומיות. בבסיס שלהן יש שרת אחד שאפשר לכתוב אליו, השרת הראשי (master או primary). עם הזמן נוספו יכולות נוספות כמו שרתי קריאה נוספים (read-only) – כלומר העתקים של השרת הראשי שמהם אפשר רק לקרוא, כדי לפזר את עומסי הקריאה. כמו גם קלאסטרים (cluster) כדי לתמוך במצב בו השרת הראשי נופל – שרת גיבוי ייכנס מיד לפעולה. Sharding ו-Partitioning יאפשרו פיצול של הטבלה או טבלאות לשרתים ראשיים שונים. יש עוד יכולות רבות שלאט לאט נותנות מענה לבעיות שונות, אבל המענים מורכבים, מסובכים, ולא תמיד נותנים את הפתרון האולטימטיבי. לעשות scale out (זוכרים? דיברנו בחלק הקודם) היא משימה מורכבת עד בלתי אפשרית וגם אם אפשרית אז לוקחת שעות רבות, ולעשות scale up לרוב יגרום להשבתה שגם יכולה לנוע בין דקות לשעות.

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

מסדי נתונים לא רלציוניים (NoSQL Databases)

עם הגלובליזציה של המידע והאינטרנט, התפתחות הענן וההבנה שצריך משהו קצת שונה – התפתחו לו סוג חדש של מסדי נתונים. כזה שלא מבוסס על טבלאות אלא מבוסס על סוגים אחרים של מידע, ייתכן ומדובר על אובייקטים מורכבים או שמדובר על מפתח-ערך, או אולי על ציר זמן. המידע כבר מורכב ושונה, יכול להיות אוסף של מידע שכל אובייקט באוסף נראה שונה מהאחר. בנוסף, מסדי נתונים אלה מאפשרים יכולות אחרות, שונות וחזקות מאלה שקיימים לאחיהם הרלציוניים. אני מדבר על מסדי נתונים לא רלציוניים, או בשמם המוכר יותר – NoSQL Databases. נוטים לומר ש-NoSQL משמעו Not Only SQL, כלומר "לא רק SQL" (ה-SQL הוא גם קיצור של Structured Query Language אבל הכוונה שלו כאן זה למסדי נתונים רגילים/רלציוניים שכדי לשלוף מהם צריך להשתמש בשאילתת SQL).

אחד ממסדי הנתונים האלה המוכרים היום הוא ה-MongoDB – ועם ארכיטקטורה נכונה הוא יכול להכיל מספר רב של שרתים על רחבי הגלובוס, משהו שקשה מאוד לבצע במסדי נתונים רלציוניים. יכול להיות לו מספר שרתים ראשיים וכן שרתי קריאה בלבד. יותר פשוט לעשות לו Scale out לפי הצורך. יש לו תכונות רבות וחזקות שפותרות חלק מהבעיות שמפגינות מסדי הנתונים הרלציוניים. מנגד – כמובן – הוא שונה מהרלציוניים, בכך שהוא פחות שומר על עקרון ה-ACID שקיים ברלציוניים. עקרון ה-ACID (ר"ת של Atomicity, Consistency, Isolation, Durability) מדבר על 4 תכונות של מסדי נתונים רלציוניים – אטומטיות, עקביות, בידוד ועמידות. אפשר להגדיר כך שיגיע לרמה גבוה וקרובה של ACID, אבל ככל שהמערכת מפוזרת ומבוזרת – נצטרך להתפשר על משהו (קרי ה-ACID) כדי להשיג משהו אחר (גמישות בלתי מוגבלת).

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

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

סיכום

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

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

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *