הסבר על שאילתות האזנה בזמן אמת בקנה מידה נרחב

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

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

בקטעים הבאים מפורטים טיפים להרחבת השימוש באפליקציה.

בחירת מיקום מסד נתונים שקרוב למשתמשים

התרשים הבא מדגים את הארכיטקטורה של אפליקציה בזמן אמת:

דוגמה לארכיטקטורת אפליקציה בזמן אמת

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

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

תכנון לאמינות

הנושאים הבאים משפרים את המהימנות של האפליקציה או מושפעים ממנה:

הפעלת מצב אופליין

ערכות ה-SDK של Firebase מספקות שמירה של נתונים במצב אופליין. אם האפליקציה במכשיר של המשתמש לא מצליחה להתחבר אל Cloud Firestore, המשתמש יכול להמשיך להשתמש באפליקציה כי היא פועלת עם נתונים שנשמרו במטמון באופן מקומי. כך המשתמשים יכולים לגשת לנתונים גם אם החיבור שלהם לאינטרנט לא יציב או אם הם מאבדים את הגישה לאינטרנט למשך כמה שעות או ימים. לפרטים נוספים על מצב אופליין, אפשר לעיין במאמר בנושא הפעלה של נתונים במצב אופליין.

הסבר על ניסיונות חוזרים אוטומטיים

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

בחירה בין מיקומים אזוריים לבין מיקומים בכמה אזורים

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

הסבר על מערכת השאילתות בזמן אמת

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

נניח שיש שני משתמשים שמתחברים ל-Cloud Firestore דרך אפליקציית הודעות שנבנתה באמצעות אחת מערכות ה-SDK לנייד.

לקוח א' כותב למסד הנתונים כדי להוסיף ולעדכן מסמכים באוסף שנקרא chatroom:

collection chatroom:
    document message1:
      from: 'Sparky'
      message: 'Welcome to Cloud Firestore!'

    document message2:
      from: 'Santa'
      message: 'Presents are coming'

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

ארכיטקטורה של חיבור מאזין לתמונת מצב

רצף האירועים הבא מתרחש כשלקוח ב' מחבר מאזין של תמונת מצב למסד הנתונים:

  1. לקוח ב' פותח חיבור אל Cloud Firestore ורושם מאזין על ידי ביצוע קריאה אל onSnapshot(collection("chatroom")) דרך Firebase SDK. המאזין הזה יכול להישאר פעיל במשך שעות.
  2. הקצה הקדמי של Cloud Firestore שולח שאילתות למערכת האחסון הבסיסית כדי לאתחל את קבוצת הנתונים. הוא טוען את כל קבוצת התוצאות של מסמכים תואמים. אנחנו קוראים לזה שאילתת בדיקה. לאחר מכן המערכת מעריכה את כללי האבטחה של Firebase במסד הנתונים כדי לוודא שלמשתמש יש גישה לנתונים האלה. אם המשתמש מורשה, מסד הנתונים מחזיר את הנתונים למשתמש.
  3. השאילתה של לקוח ב' עוברת למצב האזנה. המאזין נרשם לטיפול במינוי וממתין לעדכונים בנתונים.
  4. לקוח א' שולח עכשיו פעולת כתיבה כדי לשנות מסמך.
  5. מסד הנתונים מבצע את השינוי במסמך במערכת האחסון שלו.
  6. מבחינת טרנזקציות, המערכת מבצעת את אותו עדכון ביומן שינויים פנימי. יומן השינויים קובע סדר קפדני של השינויים בזמן שהם מתרחשים.
  7. יומן השינויים מעביר את הנתונים המעודכנים למאגר של מטפלי מינויים.
  8. התאמת שאילתות הפוכות מופעלת כדי לבדוק אם המסמך המעודכן תואם לאחד מהמאזינים ל-snapshot שרשומים כרגע. בדוגמה הזו, המסמך תואם למאזין ל-snapshot של לקוח ב'. כמו שהשם מרמז, אפשר לחשוב על התאמת שאילתות הפוכות כעל שאילתת מסד נתונים רגילה, אבל הפוכה. במקום לחפש במסמכים כדי למצוא את אלה שתואמים לשאילתה, המערכת מחפשת ביעילות בשאילתות כדי למצוא את אלה שתואמות למסמך נכנס. כשנמצאת התאמה, המערכת מעבירה את המסמך הרלוונטי למאזינים ל-snapshot. לאחר מכן, המערכת מעריכה את כללי האבטחה של Firebase במסד הנתונים כדי לוודא שרק משתמשים מורשים מקבלים את הנתונים.
  9. המערכת מעבירה את עדכון המסמך ל-SDK במכשיר של לקוח ב', ופונקציית הקריאה החוזרת onSnapshot מופעלת. אם מופעלת התמדה מקומית, אפליקציית ה-SDK מחילה את העדכון גם על המטמון המקומי.

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

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

יישום שיטות מומלצות להרחבת שאילתות בזמן אמת

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

הסבר על נפח גבוה של תנועת כתיבה במערכת

בקטע הזה מוסבר איך המערכת מגיבה למספר הולך וגדל של בקשות כתיבה.

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

ארכיטקטורה של fan-out של יומן שינויים

התאמה אוטומטית לעומס מאפשרת להגדיל את תנועת הכתיבה ללא הגבלות, אבל ככל שהתנועה גדלה, יכול להיות שיעבור זמן עד שהמערכת תגיב. כדי להימנע מיצירת נקודה חמה לכתיבה, מומלץ לפעול לפי ההמלצות של כלל 5-5-5. ‫Key Visualizer הוא כלי שימושי לניתוח נקודות חמות של כתיבה.

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

הסבר על האינטראקציה בין פעולות כתיבה וקריאה

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

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

צריך לשמור על מסמכים קטנים ועל פעולות כתיבה קטנות

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

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

שימוש ברכיבי listener יעילים

ככל ששיעורי הכתיבה במסד הנתונים עולים,‏ Cloud Firestore מפצל את עיבוד הנתונים בין שרתים רבים.‏ Cloud Firestoreאלגוריתם השארדינג של מנסה למקם נתונים מאותו אוסף או מאותה קבוצת אוספים באותו שרת של יומן השינויים. המערכת מנסה למקסם את קצב העברת הנתונים האפשרי תוך שמירה על מספר השרתים שמעורבים בעיבוד של שאילתה נמוך ככל האפשר.

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

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

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

שמירה על מהירות של שאילתות סקר

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

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

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

אם שאילתות ה-Polling שלכם מהירות מספיק, מצב ה-Polling הופך לשקוף למשתמשי האפליקציה.

עדיפות להגדרות listener לטווח ארוך

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

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

המאמרים הבאים