יישומים מקוונים בקנה מידה גדול עשו כברת דרך בשני העשורים הקודמים. חידושים אלו שינו את התפיסה שלנו לגבי פיתוח תוכנה. פייסבוק, אינסטגרם וטוויטר, למשל, הן כולן פלטפורמות הניתנות להרחבה.
מערכות אלו חייבות להיבנות לניהול כמויות עצומות של תעבורה ונתונים מכיוון שמיליארדי אנשים משתמשים בהן בו-זמנית ברחבי העולם. זה מתי עיצוב מערכת נכנס לתמונה.
תהליך הקמת הארכיטקטורה, הממשקים והנתונים עבור מערכת העומדת בקריטריונים מסוימים מכונה עיצוב מערכת. באמצעות מערכות מלוכדות ויעילות, עיצוב המערכת עונה על הדרישות של העסק או הארגון שלך.
לאחר שהחברה או הארגון שלכם קבעו את הקריטריונים שלהם, תוכלו להתחיל לשלב אותם בעיצוב מערכת פיזית העונה על דרישות הצרכנים שלכם.
בין אם תבחר ללכת לפיתוח בהתאמה אישית, פתרונות מסחריים או שילוב של השניים, האופן שבו תעצב את המערכת שלך יקבע כיצד תבנה אותה.
נסקור מפורט על עיצוב המערכת של ציר הזמן של טוויטר בפוסט זה, עם הדרכה. בואו נתחיל.
שלב 1: תאר את מקרה השימוש והאילוצים
השתמש במקרה
- משתמש מעלה ציוץ.
- השירות שולח התראות דחיפה ומיילים לעוקבי ציוצים.
- ציר הזמן של המשתמש מוצג (פעילות מהמשתמש)
- המשתמש מסתכל על ציר הזמן הביתי (פעילות מאנשים שהמשתמש עוקב אחריהם)
- מילות המפתח מתבצעות על ידי המשתמש.
- השירות ממש נגיש.
מחוץ לכוונת
- ציוצים נשלחים ל-Twitter Firehose ולזרמים אחרים באמצעות שירות זה.
- השירות מסיר ציוצים על סמך הגדרות הנראות של המשתמש.
- אם המשתמש אינו עוקב גם אחר האדם שאליו עונים, הסתר את התשובה.
- שים לב לאפשרות 'הסתר ציוצים מחדש'.
- אנליטיקה
אילוצים והנחות
הנחות המדינה
- התנועה אינה מפוזרת באופן שווה.
- זה צריך להיות פשוט לשלוח ציוץ.
- אלא אם יש לך מיליוני עוקבים, שליחת ציוץ לכל העוקבים שלך צריכה להיות מהירה.
- יש 100 מיליון משתמשים פעילים.
- 15 מיליארד ציוצים בכל חודש או 500 מיליון ציוצים בכל יום
- לכל ציוץ יש מניעה של 10 מסירות בממוצע.
- מדי יום, fanout מספקת 5 מיליארד ציוצים.
- Fanout מספקת 150 מיליארד ציוצים מדי חודש.
- 250 מיליארד בקשות קריאה חודשיות
- 10 מיליארד חיפושים חודשיים
ציר זמן
- ציר הזמן צריך להיות קל לניווט.
- טוויטר עוסק יותר בקריאה מאשר בכתיבה.
- בצע אופטימיזציה לקריאת ציוצים מהירה
- צריכת ציוצים גוזלת זמן.
חיפוש
- תהליך החיפוש צריך להיות מהיר.
- זה לוקח זמן לחפש.
חישוב שימוש
גודל כל ציוץ:
- מזהה ציוץ של 8 בתים
- מזהה משתמש של 32 בתים
- 140 בתים של טקסט
- מדיה - ממוצע של 10 KB
- סה"כ: ~10 KB
מדי חודש נוצר 150 TB של תוכן ציוץ טרי.
- * 500 מיליון ציוצים כל יום * 30 ימים בחודש * 10 KB לציוץ
- בשלוש שנים, היו 5.4 PB של תוכן ציוץ טרי.
יש 100,000 בקשות קריאה בכל שנייה.
- * (400 בקשות לשנייה / מיליארד בקשות לחודש) 1 מיליארד בקשות קריאה בכל חודש
יש 6,000 ציוצים בכל שנייה.
- * (400 בקשות בשנייה / מיליארד בקשות לחודש) 1 מיליארד ציוצים בכל חודש
ב-fanout נשלחים 60 אלף ציוצים בכל שנייה.
- Fanout מספקת 150 מיליארד ציוצים בכל חודש* (400 בקשות בשנייה / מיליארד בקשות לחודש).
4,000 בקשות למידע בכל שנייה
- * (400 בקשות לשנייה / מיליארד בקשות לחודש) 1 מיליארד חיפושים בכל חודש
כמה המרה שימושית
- כל חודש חולפות 2.5 מיליון שניות.
- 2.5 מיליון בקשות בחודש בבקשה אחת לשנייה
- 100 מיליון בקשות בחודש x 40 בקשות לשנייה
- מיליארד בקשות לחודש = 1 בקשות בשנייה
שלב 2: דיאגרמה ברמה גבוהה
שלב 3: הסבר על רכיבי הליבה
נוכל לשמור את הציוצים של המשתמש עצמו כדי לאכלס את ציר הזמן של המשתמש (פעילות מהמשתמש) במסד נתונים יחסי אם הוא ישלח ציוץ. קשה יותר להעביר ציוצים ולפתח את ציר הזמן הביתי (פעילות מאנשים שהמשתמש עוקב אחריהם).
מסד נתונים יחסי טיפוסי יהיה מוצף על ידי הפצת ציוצים לכל העוקבים (60 אלף ציוצים מועברים בכל שנייה). סביר להניח שנרצה ללכת עם אחסון נתונים לכתיבה מהירה כמו מסד נתונים NoSQL או Memory Cache.
קריאה של 1 MB ברצף מהזיכרון אורכת בערך 250 מיקרו שניות, אבל קריאה מ-SSD אורכת פי 4, וקריאה מהדיסק אורכת פי 80.
ניתן להשתמש ב-Object Store לאחסון נתונים כגון תמונות וסרטונים.
- שרת האינטרנט, שפועל כפרוקסי הפוך, מקבל ציוץ מהלקוח.
- הבקשה נשלחת לשרת ה-Write API על ידי שרת האינטרנט.
- ה-Write API שומר את הציוץ במסד נתונים של SQL בציר הזמן של המשתמש.
ה-Write API יוצר קשר עם שירות Fan-Out, והוא מבצע את המשימות הבאות.
- מוצא את העוקבים של המשתמש ב-Memory Cache על ידי שאילתה ב-User Graph Service.
- ב-Memory Cache, הציוץ נשמר בציר הזמן הביתי של העוקבים של המשתמש.
- 1,000 עוקבים = 1,000 חיפושים והוספות = פעולת O(n).
- הציוץ נשמר בשירות אינדקס החיפוש לחיפוש מהיר.
- מאגר האובייקטים משמש לאחסון מדיה.
- שולח התראות דחיפה לעוקבים דרך שירות ההתראות.
- כדי לשלוח התראות באופן אסינכרוני, הוא משתמש בתור.
אנו יכולים להשתמש ברשימת Redis מקורית עם המבנה הבא אם מטמון הזיכרון שלנו הוא Redis:
ציר הזמן הביתי של המשתמש יעודכן בציוץ החדש, שיישמר ב-Memory Cache. אנו נשתמש ב- REST API הציבורי הבא:
ציר הזמן של המשתמש נצפה על ידי המשתמש.
- שרת האינטרנט מקבל בקשת ציר זמן של המשתמש מהלקוח.
- הבקשה נשלחת לשרת Read API על ידי שרת האינטרנט.
- ה-Read API שואל את מסד הנתונים של SQL עבור מסגרת הזמן של המשתמש.
REST API יעבוד בדומה לציר הזמן הביתי, למעט שכל הציוצים יבואו מהמשתמש ולא מהאנשים שהם עוקבים אחריהם.
משתמש מחפש מילות מפתח:
- שרת האינטרנט מקבל בקשת חיפוש מהלקוח.
- הבקשה נשלחת לשרת ה-API של החיפוש על ידי שרת האינטרנט.
שלב 4: ציר הזמן של טוויטר
יצירת ציר זמן היא משימה קשה. נדרש שרת ליצירת ציר זמן המקשר לאינטרנט או לשרתי יישומים.
בכל פעם שמשתמש נכנס, שירות ציר הזמן עוקב אחר הציוצים החדשים ביותר מהמשתמשים בטבלת העוקבים ומעדכן או מרענן את ציר הזמן של המשתמש.
אנחנו לא מיישמים שום סוג של מערכת דירוג כאן; במקום זאת, אנו מניחים ש-5 הציוצים המובילים מהעוקבים של המשתמש מוצגים בציר הזמן לפי סדר זמן היצירה. אנחנו יכולים לשמור על חתך רענון של 50 ציוצים. אנו עדיין מפסיקים לרענן או לבנות ציר זמן לאחר הגעה לסף הזה עד שהמשתמש ירענן את הדף.
חששות של זמן אחזור וביצועים גבוהים יבואו מיצירת פיד משתמש חי. במקום זאת, יצירת זרם לא מקוון שניתן להציג באופן מיידי היא הדרך הטובה ביותר לשפר את הביצועים. הפעל שרתי ציר זמן ייעודיים שעושים פינג לשרת היישומים על בסיס קבוע כדי לרענן את הפיד בהתבסס על הזמן שבו הוא נוצר.
אלגוריתם הדירוג צריך לקחת בחשבון אותות חיוניים ולספק משקל כדי להבטיח שציר הזמן של המשתמש אינו נשלט על ידי חומר מאחד או יותר מהחשבונות שהם עוקבים אחריהם.
ליתר דיוק, אנחנו יכולים לבחור תכונות הקשורות לרלוונטיות של כל פריט פיד, כמו מספר לייקים, תגובות, שיתופים וזמן עדכון. יש להשתמש בכל אחד מהקריטריונים הללו כדי לדרג את הציוץ, ולאחר מכן יש להשתמש בדירוג הזה כדי להציג ציוצים על ציר הזמן.
האם עלינו להתריע כל הזמן למשתמשים כאשר תוכן חדש עבור הניוזפיד שלהם הופך זמין? משתמשים יכולים למצוא את זה מועיל לקבל התראה כאשר נתונים חדשים הופכים זמינים. עם זאת, במכשירים ניידים, כאשר השימוש בנתונים יקר למדי, הוא עלול לבזבז רוחב פס.
כתוצאה מכך, אנו יכולים לבחור שלא לדחוף נתונים למכשירים ניידים ובמקום זאת לאפשר למשתמשים "משוך כדי לרענן" עבור פרסומים חדשים.
שלב 5: עיצוב קנה מידה
צוואר בקבוק פוטנציאלי הוא שירות Fanout. משתמשי טוויטר עם מיליוני עוקבים יצטרכו לחכות מספר דקות עד שהציוצים שלהם יתגלגלו. זה עלול לגרום למירוץ עם תשובות לציוץ, ממנו נוכל להימנע על ידי סדר מחדש של הציוצים בזמן ההגשה.
נוכל גם למנוע הפצת ציוצים מאנשים עם מספר גדול של עוקבים. במקום זאת, אנו עשויים לבצע חיפוש ציוצים מאנשים במעקב רב, לשלב את תוצאות החיפוש עם תוצאות ציר הזמן הביתי של המשתמש, ולאחר מכן לסדר מחדש את הציוצים בזמן ההגשה.
שיפורים נוספים כוללים:
- שמור רק כמה מאות ציוצים ב-Memory Cache עבור כל ציר זמן ביתי.
- במטמון הזיכרון, רק מידע ציר הזמן הביתי של המשתמשים הפעילים נשמר.
- אנו יכולים לשחזר את הכרונולוגיה ממסד הנתונים של SQL אם משתמש לא היה פעיל ב-30 הימים הקודמים.
- כדי לגלות מי המשתמש, השתמש בשירות גרף המשתמש.
- הוסף את הציוצים למטמון הזיכרון על ידי אחזורם ממסד הנתונים של SQL.
- שירות המידע על ציוצים יכול לחסוך רק חודש של ציוצים.
- בשירות מידע משתמש, רק משתמשים פעילים נשמרים.
- כדי לשמור על זמן אחזור נמוך, סביר להניח שאשכול החיפוש יצטרך לשמור את הציוצים בזיכרון.
סיכום
למרות שטוויטר הוא ארגון גדול, יש לו ארגון טוב יותר הבנה של עיצוב מערכת. עשיתי כמיטב יכולתי לספק לך סקירה ברמה גבוהה של ציר הזמן של טוויטר.
אני מקווה שהשגת ממנו מידע שימושי ותוכל לנצל אותו היטב.
השאירו תגובה