איך מעצבים שירות אחסון קבצים כמו Dropbox - מקרה בוחן¶
שירות כמו Dropbox נשמע פשוט - מעלים קובץ, הוא נשמר, ומופיע בכל המכשירים שלכם. אבל מאחורי החזית הפשוטה מסתתרת בעיה מעניינת - איך מסנכרנים בין כמה מכשירים ביעילות, בלי להעלות מחדש קובץ שלם בכל פעם שמשהו קטן משתנה בו. זה מקרה בוחן טוב להבין את הפער בין "העתקת קבצים" לבין "סנכרון חכם".
שלב 1 - הגישה הנאיבית ולמה היא לא מספיקה¶
הגישה הפשוטה ביותר היא - כל שינוי בקובץ, מעלים את הקובץ המלא מחדש. זה עובד עבור קובץ טקסט קטן, אבל לא עבור סרטון של גיגה-בייט שמשתנה בכמה בייטים בלבד. גם הרוחב פס וגם הזמן שנדרש להעלאה חוזרת של קבצים גדולים הופכים את זה ללא מעשי, במיוחד עבור משתמשים עם חיבור אינטרנט לא מהיר.
שלב 2 - חלוקה לבלוקים - block-level sync¶
הפתרון המקובל הוא לפרק כל קובץ ל"בלוקים" קטנים - קטעים בגודל קבוע, למשל ארבעה מגה-בייט כל אחד. כשקובץ משתנה, הקליינט מחשב איזה בלוקים בדיוק השתנו, ומעלה רק אותם, לא את הקובץ כולו. זה מקצר דרמטית את זמן ההעלאה עבור שינויים קטנים בקבצים גדולים. כדי לזהות בלוק שהשתנה, לכל בלוק מחשבים hash - טביעת אצבע קצרה - וההשוואה בין ה-hash הישן לחדש היא זו שקובעת אם הבלוק צריך העלאה.
שלב 3 - מטא-דאטה מול תוכן בפועל¶
המערכת שומרת שני סוגי מידע נפרדים - מטא-דאטה, כמו שם הקובץ, תיקייה, הרשאות, ומי ערך אותו לאחרונה, ותוכן בפועל - הבלוקים עצמם. שני הסוגים דורשים אחסון שונה לגמרי - מטא-דאטה נשמר במסד נתונים רגיל שתומך בשאילתות מהירות, בעוד שתוכן הקבצים נשמר באחסון אובייקטים כמו S3, שמותאם לאחסון כמויות עצומות של נתונים גדולים בעלות נמוכה. הפרדה כזאת מאפשרת לכל חלק להתמדרג בקצב משלו.
שלב 4 - דדופליקציה - חיסכון אמיתי בקנה מידה¶
בשירות עם מיליוני משתמשים, הרבה בלוקים זהים חוזרים על עצמם - קובץ פופולרי ששותפו הרבה אנשים, או תבנית מסמך סטנדרטית. במקום לשמור עותק נפרד של אותו בלוק בדיוק לכל משתמש, המערכת שומרת בלוק אחד פיזית, ומצביעה עליו מכמה מקומות שונים באמצעות ה-hash שלו. זו טכניקת דדופליקציה שחוסכת כמות אחסון עצומה בקנה מידה גדול, בלי שהמשתמש בכלל מרגיש שינוי כלשהו בחוויה.
שלב 5 - סנכרון בין מכשירים והתראה על שינויים¶
כשמכשיר אחד מעלה שינוי, כל שאר המכשירים המחוברים לאותו חשבון צריכים לדעת עליו ולמשוך את השינוי. פתרון נפוץ הוא ערוץ התראות בזמן אמת - כשקובץ משתנה, השרת שולח הודעת "משהו השתנה" לכל המכשירים המחוברים, ואלה מושכים את רשימת השינויים ומעדכנים את עצמם. זה דומה במהותו לרעיון שדיברנו עליו במקרה הבוחן על אפליקציית צ'אט - חיבור ארוך טווח שמאפשר לשרת ליזום עדכון לקליינט.
שלב 6 - התנגשויות עריכה בין מכשירים¶
מה קורה אם שני מכשירים עורכים את אותו קובץ בו זמנית, כשאחד מהם היה במצב לא מקוון? זו בעיה קלאסית של התנגשות עדכונים. הפתרון הנפוץ ביותר בפועל הוא לא לנסות למזג את השינויים אוטומטית - אלא לשמור את שתי הגרסאות בנפרד, ולסמן את אחת מהן כ"עותק מסונכרן" עם שם קובץ מעודכן, ולתת למשתמש להחליט ידנית מה לעשות. ניסיון מיזוג אוטומטי חכם יותר אפשרי לגבי סוגי קבצים מסוימים, כמו מסמכי טקסט משותפים, אבל דורש תשתית נפרדת ומורכבת בהרבה.
מקרה הבוחן הזה ממחיש איך בעיה שנראית פשוטה - "שמירת קובץ" - הופכת מורכבת ברגע שמכניסים לתמונה כמה מכשירים, קבצים גדולים, ומיליוני משתמשים. בקורס ארכיטקטורת תוכנה שלנו עוברים על מקרי בוחן דומים ומראים איך לפרק אותם לשלבים ברי ניהול.
עיצבתם מערכת סנכרון קבצים והתמודדתם עם התנגשות עריכה? הצטרפו לקהילה בדיסקורד ותספרו איך פתרתם.
לסיכום¶
שירות אחסון קבצים כמו Dropbox בנוי סביב פירוק קבצים לבלוקים קטנים, כדי להעלות רק מה שהשתנה בפועל, הפרדה בין מטא-דאטה לתוכן, ודדופליקציה שחוסכת אחסון בקנה מידה גדול. החלק הקשה באמת אינו העלאת קובץ יחיד, אלא סנכרון עקבי בין כמה מכשירים וטיפול הוגן בהתנגשויות כשעריכות מתרחשות בו זמנית.