מערכות תוכנה בענן: איך מתכננים תשתית שיכולה לצמוח עם העסק
מערכות תוכנה מודרניות כמעט תמיד נדרשות להשתנות עם הזמן. מספר המשתמשים גדל, מצטרפות אינטגרציות חדשות, נפח המידע עולה, דרישות האבטחה משתנות ולעיתים גם המודל העסקי עצמו מתפתח.
במצב כזה, התשתית שעליה המערכת פועלת הופכת לחלק משמעותי מאוד מהיכולת של העסק לצמוח.
המעבר לענן הפך בשנים האחרונות לבחירה טבעית עבור חברות רבות, אך חשוב להבין שעצם השימוש בשירותי ענן אינו מבטיח שמערכת תהיה גמישה, יציבה או קלה להרחבה. תשתית טובה היא תוצאה של תכנון נכון, לא של בחירת ספק כזה או אחר.
השאלה המרכזית אינה רק איפה המערכת תרוץ, אלא איך היא תיבנה כך שתוכל להתמודד עם הצרכים של היום בלי להגביל את האפשרויות של מחר.
מה המשמעות של מערכת תוכנה בענן
כאשר מדברים על מערכת בענן, הכוונה בדרך כלל למערכת שפועלת על גבי תשתיות מחשוב שמסופקות כשירות, במקום להסתמך רק על שרתים פיזיים שנמצאים אצל החברה עצמה.
הענן מאפשר להשתמש במשאבי מחשוב, אחסון, בסיסי נתונים, שירותי תקשורת, מערכות ניטור וכלים נוספים לפי הצורך.
אבל חשוב להפריד בין שני דברים שונים:
מערכת שרצה בענן, ומערכת שתוכננה נכון לעבודה בענן.
אפשר לקחת מערכת ישנה, להעביר אותה לשרת וירטואלי בענן ולהמשיך לעבוד כמעט באותה צורה בדיוק. זו עדיין מערכת בענן מבחינה טכנית, אבל היא לא בהכרח מנצלת את היתרונות של הסביבה החדשה.
תכנון נכון בוחן כיצד המערכת צריכה להתנהג כאשר העומס משתנה, כאשר רכיב מסוים נופל, כאשר צריך להוסיף שירות חדש או כאשר יש צורך להתרחב לאזור גיאוגרפי נוסף.
מתחילים מהצרכים של המוצר
אחת הטעויות הנפוצות בתכנון תשתיות היא להתחיל מהטכנולוגיה.
איזה Cloud Provider לבחור? האם להשתמש ב־Kubernetes? האם צריך Microservices? כמה שרתים נרצה להפעיל?
אלה שאלות חשובות, אבל הן לא צריכות להיות הראשונות.
לפני הכול צריך להבין מה המוצר צריך לעשות.
כמה משתמשים צפויים להשתמש במערכת?
האם השימוש רציף לאורך היום או שקיימים עומסי שיא?
האם המערכת מעבדת קבצים כבדים?
האם קיימת פעילות בזמן אמת?
האם חלק מהמשתמשים נמצאים במדינות שונות?
האם קיימות אינטגרציות חיצוניות שהמערכת תלויה בהן?
רק לאחר שמבינים את דפוסי השימוש אפשר לתכנן תשתית שמתאימה למציאות במקום לתרחיש תיאורטי.
לא כל מערכת צריכה תשתית מורכבת
בעולם הטכנולוגיה קל מאוד להיסחף לפתרונות מתקדמים.
אפשר לבנות מערכת עם עשרות שירותים, Containers, מערכות Orchestration ושכבות רבות של Infrastructure.
השאלה היא האם המוצר באמת צריך את זה.
עבור מערכת עם מאות משתמשים, צוות פיתוח קטן ודרישות פשוטות יחסית, תשתית פשוטה יכולה להיות יתרון גדול.
פחות רכיבים פירושם בדרך כלל:
פחות נקודות כשל,
פחות מורכבות תפעולית,
פחות עלויות,
ופחות זמן שהצוות צריך להשקיע בתחזוקה.
המורכבות צריכה להגיע כאשר קיים צורך אמיתי, לא משום שטכנולוגיה מסוימת נחשבת מודרנית.
תכנון לצמיחה בלי לבנות יתר על המידה
מצד שני, גם מערכת קטנה צריכה לקחת בחשבון את האפשרות שהיא תגדל.
אין צורך לבנות מהיום הראשון Infrastructure שמתאים למיליוני משתמשים אם המוצר עדיין בתחילת הדרך, אבל כדאי להימנע מהחלטות שיהפכו כל צמיחה עתידית לשכתוב.
לדוגמה, מערכת יכולה להתחיל עם שרת אפליקציה אחד ובסיס נתונים אחד, אבל כדאי שהקוד לא יהיה תלוי בכך שיש רק instance יחיד.
אם בעתיד נרצה להפעיל כמה instances במקביל, המערכת צריכה להיות מסוגלת לעבוד בצורה נכונה גם במבנה כזה.
זו בדיוק הגישה הנכונה לצמיחה:
לא לבנות מראש את כל התשתית של העתיד, אבל לא לחסום את הדרך אליה.
Scalability היא לא רק עוד שרתים
כאשר מדברים על Scaling, רבים חושבים בעיקר על הוספת כוח מחשוב.
אבל מערכת יכולה להיתקל במגבלות במקומות רבים.
לדוגמה:
בסיס הנתונים יכול להפוך לצוואר בקבוק.
Service חיצוני יכול להגביל את מספר הקריאות.
פעולת Background יכולה לקחת זמן רב מדי.
שאילתה מסוימת יכולה להיות יקרה.
קבצים יכולים לתפוס נפח גדול.
לכן Scalability היא קודם כול שאלה ארכיטקטונית.
צריך להבין אילו חלקים במערכת צפויים לגדול ואיך הם מושפעים מהשימוש.
Scaling אנכי מול Scaling אופקי
יש שתי דרכים בסיסיות להגדיל יכולת של מערכת.
Scaling אנכי
מגדילים את המשאבים של אותו שרת:
יותר CPU,
יותר Memory,
יותר Storage.
זו גישה פשוטה ולעיתים יעילה מאוד.
Scaling אופקי
מוסיפים עוד instances של האפליקציה ומחלקים ביניהם את העומס.
זו גישה שמאפשרת לצמוח רחוק יותר, אבל דורשת שהמערכת תתוכנן בהתאם.
לדוגמה, אם Session של משתמש נשמר בזיכרון של שרת אחד בלבד, משתמש שעובר לשרת אחר עלול לאבד את ה־Session שלו.
לכן החלטות שנראות קטנות בזמן הפיתוח יכולות להשפיע מאוד על היכולת לבצע Scaling בהמשך.
בסיס הנתונים הוא אחד הרכיבים החשובים ביותר
אפליקציה יכולה להתרחב יחסית בקלות אם היא Stateless.
בסיס הנתונים מורכב יותר.
הוא מחזיק את המידע המרכזי של המערכת ולכן שינויים סביבו דורשים יותר זהירות.
כדאי לחשוב מראש על:
מבנה הנתונים,
Indexing,
שאילתות כבדות,
גיבויים,
Replication,
Retention,
והיקף הגידול הצפוי.
אין צורך לבחור מיד Database "גדול" או מורכב.
במקרים רבים PostgreSQL, MySQL או פתרון Managed מתאים יכולים לשרת מוצר במשך שנים.
הדגש צריך להיות על שימוש נכון ולא על בחירת הטכנולוגיה הכי מרשימה.
Managed Services יכולים לחסוך הרבה עבודה
אחד היתרונות הגדולים של הענן הוא האפשרות להשתמש בשירותים מנוהלים.
במקום שהצוות יתחזק בעצמו:
Database,
Message Queue,
Object Storage,
Monitoring,
Backups,
אפשר לעיתים להשתמש בשירות שמנוהל על ידי ספק התשתית.
היתרון הוא פחות עבודה תפעולית ופחות אחריות על שכבות שאינן הליבה העסקית של המוצר.
החיסרון יכול להיות עלות גבוהה יותר או תלות בספק מסוים.
לכן השאלה היא לא האם Managed Service "טוב יותר", אלא האם הוא מתאים לגודל הצוות ולמוצר.
זמינות ואמינות
כאשר מערכת הופכת לחלק משמעותי מהפעילות העסקית, אי אפשר להסתפק בשאלה האם היא עובדת בדרך כלל.
צריך להבין מה קורה כאשר משהו נכשל.
שרת נופל.
Database הופך זמנית ללא זמין.
API חיצוני מפסיק להגיב.
Deploy חדש מכניס Bug.
מערכת טובה צריכה להיות מסוגלת להתמודד עם חלק מהמצבים האלה בצורה מבוקרת.
זה לא אומר שכל מערכת צריכה High Availability ברמה של בנק.
אבל כן צריך להגדיר מראש מהי רמת הזמינות הנדרשת לעסק.
גיבויים הם רק חצי מהפתרון
כמעט כל מערכת מבצעת Backup.
השאלה החשובה יותר היא:
האם אפשר באמת לשחזר ממנו?
Backup שלא נבדק יכול לתת תחושת ביטחון שגויה.
לכן כדאי להגדיר:
באיזו תדירות מתבצע גיבוי?
כמה זמן הוא נשמר?
האם קיימים כמה עותקים?
כמה זמן ייקח לבצע Restore?
כמה מידע אפשר להרשות לעצמנו לאבד במקרה של תקלה?
אלה שאלות עסקיות לא פחות מטכנולוגיות.
אבטחת מידע צריכה להיות חלק מהתשתית
תשתית ענן מספקת כלים רבים לאבטחה, אבל היא לא הופכת מערכת למאובטחת באופן אוטומטי.
צריך לנהל נכון:
הרשאות,
Credentials,
Secrets,
Firewall rules,
גישה ל־Database,
גישה ל־Storage,
והפרדה בין סביבות.
אחד העקרונות החשובים הוא Least Privilege.
כל משתמש וכל Service צריכים לקבל רק את ההרשאות שהם באמת צריכים.
ככל שהמערכת גדלה, ניהול ההרשאות הופך חשוב יותר.
הפרדה בין סביבות
מערכת מקצועית בדרך כלל לא עובדת בסביבה אחת בלבד.
מקובל להפריד לפחות בין:
Development,
Testing או QA,
Staging,
Production.
המטרה היא לאפשר לצוות לבצע שינויים ובדיקות מבלי לסכן את המערכת שבה משתמשים הלקוחות.
הפרדה כזו גם מסייעת בניהול Secrets, מידע אמיתי, גרסאות ותהליכי Deployment.
כאשר כל הסביבות מעורבבות, כל שינוי הופך למסוכן יותר.
CI/CD ותהליך העלאת גרסאות
תהליך Deployment ידני יכול לעבוד כאשר מוצר קטן מאוד.
ככל שהמערכת גדלה, כדאי להפוך את תהליך העלאת הגרסאות לעקבי ואוטומטי יותר.
CI/CD מאפשר לצוות לבצע:
Build,
Tests,
Validation,
Deployment,
בצורה מוגדרת מראש.
המטרה אינה לבצע Deployment בכל שעה רק משום שאפשר.
המטרה היא לצמצם טעויות אנוש וליצור תהליך שאפשר לחזור עליו בצורה בטוחה.
ניטור הוא חלק מהמוצר
מערכת יכולה להיות "באוויר" ועדיין לעבוד רע.
לכן Monitoring אינו רק בדיקה שהשרת פעיל.
כדאי למדוד גם:
זמני תגובה,
שגיאות,
צריכת משאבים,
עומס על Database,
כישלונות של Background Jobs,
זמינות של שירותים חיצוניים.
במערכות מתקדמות יותר כדאי גם למדוד מדדים שהמשתמש באמת מרגיש.
לדוגמה:
כמה זמן לוקח לבצע פעולה מרכזית?
כמה בקשות נכשלות?
כמה זמן עובר מרגע פעולה עד שהמידע מתעדכן?
תשתית טובה צריכה לאפשר לצוות לזהות בעיה לפני שהמשתמש מתקשר לתמיכה.
Observability ולא רק Logs
Logs חשובים, אבל הם רק חלק מהתמונה.
כאשר מערכת כוללת כמה שירותים, לפעמים קשה להבין מה קרה ל־Request מסוים.
לכן משלבים גם:
Metrics,
Tracing,
Alerts.
השילוב בין הכלים האלה מאפשר לצוות להבין היכן נוצרה תקלה ובאיזה רכיב.
ככל שהמערכת מבוזרת יותר, החשיבות של Observability עולה.
עלויות ענן צריכות להיות חלק מהתכנון
הענן מאפשר להגדיל משאבים בקלות, אבל אותה גמישות יכולה גם להפוך לעלויות לא מבוקרות.
Storage גדל.
Logs נשמרים שנים.
Servers נשארים פעילים גם כשאין צורך.
Database מקבל configuration גדול בהרבה ממה שהמערכת באמת דורשת.
לכן כדאי למדוד ולנהל את עלויות הענן לאורך זמן.
Cost Optimization אינו אומר לבחור תמיד את האפשרות הזולה ביותר.
המטרה היא להבין על מה משלמים והאם העלות תואמת את הערך העסקי.
לבחור תשתית לפי הצוות
הארכיטקטורה הטובה ביותר על הנייר אינה תמיד הארכיטקטורה הטובה ביותר עבור החברה.
אם יש צוות קטן, תשתית שדורשת מומחיות עמוקה ב־Kubernetes, Networking ו־Distributed Systems יכולה להפוך לעומס משמעותי.
לעומת זאת, ארגון עם צוות DevOps ייעודי ודרישות Scale גבוהות יכול להפיק ערך רב מפתרונות מתקדמים יותר.
לכן צריך להתאים את התשתית לא רק למוצר אלא גם ליכולת של האנשים שיתחזקו אותה.
מתי Microservices באמת מתאימים
Microservices הפכו למונח נפוץ מאוד בעולם פיתוח התוכנה.
הגישה מאפשרת להפריד מערכת לשירותים עצמאיים יחסית, שכל אחד אחראי על תחום מסוים.
במערכות גדולות זו יכולה להיות דרך מצוינת לאפשר לצוותים שונים לעבוד בצורה עצמאית ולבצע Scaling לחלקים שונים.
אבל יש לזה מחיר.
צריך להתמודד עם:
תקשורת בין שירותים,
Deployment נפרד,
Monitoring,
Data consistency,
Service discovery,
Retries,
Failures.
לכן למוצר בתחילת הדרך, Monolith מסודר יכול להיות בחירה טובה בהרבה.
ארכיטקטורה פשוטה אינה ארכיטקטורה פחות מקצועית.
מתי נכון להשתמש ב־Containers
Containers כמו Docker הפכו לכלי נפוץ בפיתוח ובענן.
הם מאפשרים לארוז את האפליקציה יחד עם הסביבה שלה בצורה עקבית.
כך קל יותר לוודא שהקוד עובד בצורה דומה על מחשב המפתח, בסביבת QA וב־Production.
היתרונות כוללים:
Deployment עקבי,
Isolation,
ניידות יחסית בין סביבות.
אבל גם כאן, Container אינו פתרון לכל בעיה.
אפשר להשתמש ב־Docker בלי Kubernetes, ולעיתים זה כל מה שהמערכת צריכה.
תשתית טובה צריכה לאפשר שינוי
אחד הדברים החשובים ביותר בתכנון מערכות תוכנה הוא לקבל מראש את העובדה שהדרישות ישתנו.
אולי היום יש משתמשים רק בישראל ובעתיד יהיו גם באירופה.
אולי היום המערכת עובדת מול ספק סליקה אחד ובהמשך יתווסף אחר.
אולי מוצר שהיה פנימי יהפוך בעתיד ל־SaaS.
אי אפשר לנבא הכול.
המטרה של ארכיטקטורה טובה היא לא לחזות את העתיד במדויק, אלא לאפשר למערכת להשתנות בלי שכל שינוי יהפוך לפרויקט בפני עצמו.
הקשר בין תשתית לפיתוח התוכנה
פיתוח האפליקציה והתשתית אינם שני פרויקטים נפרדים.
החלטה שמתקבלת בקוד יכולה להשפיע על Scaling.
מבנה Database משפיע על ביצועים.
דרך שמירת הקבצים משפיעה על עלויות.
אופן ניהול Sessions משפיע על האפשרות להוסיף Servers.
לכן בפרויקטים של פיתוח מערכות תוכנה מורכבות, כדאי שצוות הפיתוח והתשתיות יעבדו מתוך אותה תמונה ארכיטקטונית ולא ייפגשו רק בשלב העלייה ל־Production.
Cloud Native אינו יעד בפני עצמו
לפעמים חברות מגדירות מטרה להיות "Cloud Native" בלי להגדיר מה הן רוצות להשיג.
הענן הוא כלי.
אם הוא מאפשר:
להשיק מהר יותר,
לגדול בקלות יותר,
לשפר זמינות,
להקטין עומס תחזוקה,
או לקבל גישה לשירותים שלא היה משתלם להקים לבד,
יש לו ערך ברור.
אם הוא רק מוסיף שכבות של מורכבות בלי לפתור בעיה אמיתית, כדאי לעצור ולבחון את ההחלטה מחדש.
מתי כדאי לבצע שינוי בתשתית קיימת
לא כל מערכת קיימת צריכה לעבור שינוי גדול.
אם היא יציבה, מתאימה לעומס, העלויות סבירות והצוות מצליח לעבוד איתה, ייתכן שאין סיבה לגעת בה רק כדי להשתמש בטכנולוגיה חדשה.
לעומת זאת, כדאי לבדוק שינוי כאשר:
קשה לבצע Deployments,
המערכת נופלת בעומסים,
העלויות אינן צפויות,
קשה לגדול,
התחזוקה דורשת יותר מדי זמן,
או ששינויים קטנים הופכים למסובכים.
במקרים רבים ניתן לבצע Modernization בהדרגה במקום Rewrite מלא.
איך יודעים שתכנון התשתית נכון
אין מדד אחד.
אבל יש כמה סימנים טובים:
המערכת יציבה.
הצוות מסוגל להעלות גרסאות בביטחון.
אפשר לזהות תקלות מהר.
עלויות הענן ברורות.
אפשר להוסיף משתמשים או שירותים בלי שינוי דרמטי.
המערכת אינה מורכבת יותר ממה שהמוצר דורש.
וזו אולי הנקודה החשובה ביותר.
תשתית טובה היא תשתית שכמעט לא חושבים עליה ביום־יום.
היא פשוט מאפשרת למוצר לעבוד.
לסיכום
המעבר לענן פתח בפני עסקים אפשרויות שבעבר דרשו השקעה גדולה מאוד בתשתיות פיזיות.
אבל עצם השימוש בענן אינו מספיק.
היכולת לצמוח תלויה באופן שבו המערכת כולה מתוכננת: הארכיטקטורה, בסיס הנתונים, ניהול העומסים, האבטחה, הגיבויים, תהליכי ה־Deployment והניטור.
הגישה הנכונה אינה לבנות מהיום הראשון מערכת שמתאימה לכל תרחיש עתידי, וגם לא לבנות פתרון זמני שאין דרך להרחיב.
המטרה היא למצוא את נקודת האיזון: מערכת פשוטה מספיק כדי להיות קלה לפיתוח ולתחזוקה, אבל מסודרת וגמישה מספיק כדי לצמוח יחד עם העסק.
בסופו של דבר, תשתית ענן טובה לא נמדדת בכמות השירותים שבה משתמשים, אלא ביכולת שלה לאפשר למוצר להתפתח בלי להפוך בעצמה למכשול.
