אתם יכולים להשתמש בשיטות המומלצות שמפורטות כאן כחומר עזר קצר כשמפתחים אפליקציה שמשתמשת ב-Cloud Firestore.
המיקום של מסד הנתונים
כשיוצרים מכונה של מסד נתונים, בוחרים את מיקום מסד הנתונים הקרוב ביותר למשתמשים ולמשאבי המחשוב. צעדי רשת רחבים יותר נוטים יותר לשגיאות ומאריכים את זמן האחזור של השאילתה.
כדי שהזמינות והעמידות של האפליקציה תהיה מקסימלית, כדאי לבחור מיקום במספר אזורים ולהציב משאבי מחשוב קריטיים בשני אזורים לפחות.
בוחרים מיקום אזורי לעלויות נמוכות יותר, לצורך זמן אחזור קצר יותר אם האפליקציה רגישה לזמן האחזור, או למיקום משותף עם משאבים אחרים של GCP.
מזהי מסמכים
- אין להשתמש במזהי המסמכים
.
ו-..
. - במזהי מסמכים אין להשתמש בקו נטוי
/
לפנים. אסור להשתמש במזהי מסמכים שמתחזקים באופן מונוטוני, כמו:
Customer1
,Customer2
,Customer3
, ...Product 1
,Product 2
,Product 3
, ...
מזהים רציפים כאלה יכולים להוביל לנקודות לשיתוף אינטרנט שמשפיעות על זמן האחזור.
שמות שדות
מומלץ להימנע מהתווים הבאים בשמות השדות, כי הם דורשים תו בריחה נוסף:
- תקופת
.
[
סוגר מרובע שמאלי]
סוגר מרובע ימני- כוכבית
*
`
גרש הפוך
- תקופת
מדדים
מפחיתים את זמן האחזור לכתיבה
הגורם העיקרי שמשפיע על זמן האחזור של הכתיבה הוא היקף ההפצה של האינדקס. השיטות המומלצות לצמצום היקף ההסתעפות של האינדקס הן:
להגדיר החרגות להוספה לאינדקס ברמת האוסף. ברירת המחדל הקלה היא להשבית את האפשרויות 'ירידה' ו'יצירת אינדקס של מערך'. הסרה של ערכים שנוספו לאינדקס שלא נמצאים בשימוש תעזור להפחית גם את עלויות האחסון.
צמצום מספר המסמכים בעסקה. כשמעיינים במספר גדול של מסמכים, מומלץ להשתמש בבורר ראשי במקום בבורר ראשי אטומי.
פטורים מהוספה לאינדקס
ברוב האפליקציות, אפשר להסתמך על הוספה אוטומטית לאינדקס ועל קישורים להודעות שגיאה כדי לנהל את האינדקסים. עם זאת, כדאי להוסיף החרגות של שדה יחיד במקרים הבאים:
נרתיק | תיאור |
---|---|
שדות מחרוזות גדולים | אם יש לכם שדה מחרוזת שמכיל לעיתים קרובות ערכים ארוכים של מחרוזות שאתם לא משתמשים בהם לשאילתות, תוכלו לצמצם את עלויות האחסון על ידי החרגת השדה מהוספה לאינדקס. |
שיעורי כתיבה גבוהים לאוסף שמכיל מסמכים עם ערכים רציפים | אם מוסיפים לאינדקס שדה שגדל או יורד ברצף בין מסמכים באוסף, כמו חותמת זמן, קצב הכתיבה המקסימלי באוסף הוא 500 כתיבות בשנייה. אם אתם לא שולחים שאילתות על סמך השדה עם הערכים הרצופיים, תוכלו לפטור את השדה מהוספה לאינדקס כדי לעקוף את המגבלה הזו. לדוגמה, בתרחיש שימוש ב-IoT עם קצב כתיבה גבוה, אוסף שמכיל מסמכים עם שדה חותמת זמן עשוי להתקרב למגבלה של 500 פעולות כתיבה לשנייה. |
שדות TTL |
אם אתם משתמשים במדיניות TTL (זמן חיים), חשוב לדעת ששדה ה-TTL חייב להיות חותמת זמן. ההוספה לאינדקס של שדות TTL מופעלת כברירת מחדל, ויכולה להשפיע על הביצועים בשיעורי תנועה גבוהים יותר. מומלץ להוסיף פטורים בשדה יחיד לשדות ה-TTL. |
שדות גדולים של מערך או מפה | שדות גדולים של מפות או מערכי נתונים עלולים להגיע למגבלה של 40,000 רשומות באינדקס לכל מסמך. אם אתם לא שולחים שאילתות על סמך מערך גדול או שדה מפה, כדאי לפטור אותם מהוספה לאינדקס. |
פעולות קריאה וכתיבה
הקצב המקסימלי המדויק שבו אפליקציה יכולה לעדכן מסמך יחיד תלוי מאוד בעומס העבודה. למידע נוסף, ראו עדכונים במסמך יחיד.
כשהדבר אפשרי, השתמשו בקריאות אסינכרוניות במקום בקריאות סינכרוניות. קריאות אסינכרוניות ממזערות את ההשפעה על זמן האחזור. לדוגמה, נבחן אפליקציה שצריך לקבל את התוצאה של חיפוש מסמך ואת התוצאות של שאילתה לפני עיבוד התשובה. אם אין תלות בנתונים בין החיפוש לבין השאילתה, אין צורך להמתין באופן סינכרוני עד שהחיפוש יסתיים לפני שמתחילים את השאילתה.
אין להשתמש בהיסטים. במקום זאת, משתמשים בסמן. השימוש בהיסט מונע רק את החזרת המסמכים שהושמטו לאפליקציה, אבל המסמכים האלה עדיין מאוחזרים באופן פנימי. המסמכים שהושמטים משפיעים על זמן האחזור של השאילתה, והאפליקציה שלכם מחויבת על פעולות הקריאה שנדרשות כדי לאחזר אותם.
ניסיונות חוזרים של עסקאות
ערכות ה-SDK וספריות הלקוח של Cloud Firestore מנסים שוב באופן אוטומטי עסקאות שנכשלו כדי לטפל בשגיאות זמניות. אם האפליקציה שלכם ניגשת ל-Cloud Firestore דרך ממשקי ה-API של REST או RPC ישירות, במקום דרך SDK, עליכם להטמיע באפליקציה ניסיונות חוזרים של טרנזקציות כדי לשפר את האמינות.
עדכונים בזמן אמת
למידע על שיטות מומלצות שקשורות לעדכונים בזמן אמת, ראו הסבר על שאילתות בזמן אמת בקנה מידה נרחב.
תכנון לפי קנה מידה
בשיטות המומלצות הבאות מוסבר איך להימנע ממצבים שיוצרים בעיות של תחרות על משאבים.
עדכונים למסמך יחיד
כשיוצרים אפליקציה, חשוב להביא בחשבון את המהירות שבה האפליקציה מעדכנת מסמכים בודדים. הדרך הטובה ביותר לאפיין את ביצועי עומס העבודה היא לבצע בדיקות עומסים. הקצב המקסימלי המדויק שבו אפליקציה יכולה לעדכן מסמך יחיד תלוי מאוד בעומס העבודה. הגורמים כוללים את שיעור הכתיבה, את התחרות בין הבקשות ואת מספר האינדקסים שהושפעו.
פעולת כתיבת מסמך מעדכנת את המסמך ואת כל האינדקסים המשויכים, ו-Cloud Firestore מחילה את פעולת הכתיבה באופן סינכרוני על רוב קוורום של רפליקות. כששיעורי הכתיבה גבוהים מספיק, תחילה תהיה תחרות על משאבים, זמן אחזור ארוך יותר או שגיאות אחרות במסד הנתונים.
שיעורי קריאה, כתיבה ומחיקה גבוהים בטווח מצומצם של מסמכים
יש להימנע משיעור קריאה או כתיבה גבוה כדי לסגור מסמכים לפי סדר אלפביתי, אחרת האפליקציה תתקל בשגיאות תחרות. הבעיה הזו נקראת נקודה לשיתוף אינטרנט (Hotspot), והאפליקציה יכולה לחוות נקודה לשיתוף אינטרנט (Hotspot) אם היא מבצעת אחת מהפעולות הבאות:
יוצר מסמכים חדשים ברקצב גבוה ומקצה מזהי monotonically increasing משלו.
Cloud Firestore מקצה מזהי מסמכים באמצעות אלגוריתם פיזור. אם יוצרים מסמכים חדשים באמצעות מזהי מסמכים אוטומטיים, לא צריך להיתקל בנקודה לשיתוף אינטרנט (Hotspot) בכתיבה.
יצירת מסמכים חדשים בקצב גבוה באוסף עם מעט מסמכים.
יצירת מסמכים חדשים עם שדה בעל עלייה מונוטונית, כמו חותמת זמן, בקצב גבוה מאוד.
מחיקה של מסמכים באוסף בקצב גבוה.
כתיבה במסד הנתונים בקצב גבוה מאוד, בלי להגדיל בהדרגה את נפח התנועה.
הימנעות מדילוג על נתונים שנמחקו
כדאי להימנע משאילתות שמדלגות על נתונים שנמחקו לאחרונה. יכול להיות ששאילתה תצטרך לדלג על מספר גדול של רשומות באינדקס אם תוצאות השאילתה המוקדמות נמחקו לאחרונה.
דוגמה לעומס עבודה שעשוי לפספס הרבה נתונים שנמחקו היא עומס עבודה שמנסה למצוא את פריטי העבודה הישנים ביותר בתור. השאילתה עשויה להיראות כך:
docs = db.collection('WorkItems').order_by('created').limit(100)
delete_batch = db.batch()
for doc in docs.stream():
finish_work(doc)
delete_batch.delete(doc.reference)
delete_batch.commit()
בכל פעם שהשאילתה הזו פועלת, היא סורקת את הרשומות באינדקס של השדה created
בכל מסמך שנמחק לאחרונה. הפעולה הזו גורמת להאטת השאילתות.
כדי לשפר את הביצועים, כדאי להשתמש בשיטה start_at
כדי למצוא את המקום הטוב ביותר להתחיל בו. לדוגמה:
completed_items = db.collection('CompletionStats').document('all stats').get()
docs = db.collection('WorkItems').start_at(
{'created': completed_items.get('last_completed')}).order_by(
'created').limit(100)
delete_batch = db.batch()
last_completed = None
for doc in docs.stream():
finish_work(doc)
delete_batch.delete(doc.reference)
last_completed = doc.get('created')
if last_completed:
delete_batch.update(completed_items.reference,
{'last_completed': last_completed})
delete_batch.commit()
הערה: בדוגמה שלמעלה נעשה שימוש בשדה בעל עלייה מונוטונית, שהוא דפוס הפוך לקצבי כתיבה גבוהים.
הגדלת נפח התנועה
כדאי להגביר בהדרגה את התנועה לאוספים חדשים או לסגור מסמכים לקסיקוגרפיה כדי לתת ל-Cloud Firestore מספיק זמן להכין את המסמכים להגדלת התנועה. מומלץ להתחיל עם 500 פעולות לכל היותר לשנייה באוסף חדש, ולאחר מכן להגדיל את נפח התנועה ב-50% כל 5 דקות. אפשר להגדיל באופן דומה את תעבורת הכתיבה, אבל חשוב לזכור את המגבלות הרגילות של Cloud Firestore. חשוב לוודא שהפעולות מפוזרות באופן שווה יחסית בטווח המפתחות. הכלל הזה נקרא '500/50/5'.
העברת תנועה לאוסף חדש
חשוב במיוחד להגדיל את נפח התנועה בהדרגה אם מעבירים תנועה מאפליקציה מאוסף אחד לאוסף אחר. אחת הדרכים הפשוטות לטפל בהעברה הזו היא לקרוא מהאוסף הישן, ואם המסמך לא קיים, אז לקרוא מהאוסף החדש. עם זאת, הפעולה הזו עלולה לגרום לעלייה פתאומית בנפח התנועה למסמכים שסמוכים למסמכים האלה באלפבית בתוך האוסף החדש. יכול להיות ש-Cloud Firestore לא יוכל להכין ביעילות את האוסף החדש לתנועה מוגברת, במיוחד כשהוא מכיל מעט מסמכים.
בעיה דומה יכולה להתרחש אם משנים את מזהי המסמכים של הרבה מסמכים באותו אוסף.
האסטרטגיה הטובה ביותר להעברת תעבורת הנתונים לאוסף חדש תלויה במודל הנתונים שלכם. בהמשך מופיעה דוגמה לאסטרטגיה שנקראת קריאות מקבילות. תצטרכו להחליט אם השיטה הזו יעילה לנתונים שלכם, וחשוב לזכור תהיה ההשפעה על העלויות של פעולות מקבילות במהלך ההעברה.
קריאות מקבילות
כדי להטמיע קריאות מקבילות בזמן העברת התנועה לאוסף חדש, קודם צריך לקרוא מהאוסף הישן. אם המסמך חסר, המערכת תקריא מהאוסף החדש. שיעור גבוה של קריאות למסמכים לא קיימים עלול להוביל לנקודות חמות, לכן חשוב להגדיל בהדרגה את העומס על האוסף החדש. שיטה טובה יותר היא להעתיק את המסמך הישן לאוסף החדש ואז למחוק את המסמך הישן. מומלץ להגדיל בהדרגה את מספר הקריאות במקביל כדי לוודא ש-Cloud Firestore יכול לטפל בתנועה לאוסף החדש.
אסטרטגיה אפשרית להגדלת מספר הקריאות או הכתיבות לאוסף חדש בהדרגה היא להשתמש בגיבוב דטרמיניסטי של מזהה המשתמש כדי לבחור אחוז אקראי של משתמשים שמנסים לכתוב מסמכים חדשים. חשוב לוודא שהתוצאה של גיבוב מזהה המשתמש לא מוטה על ידי הפונקציה או על ידי התנהגות המשתמש.
בינתיים, מריצים משימה באצווה שמעתיקה את כל הנתונים מהמסמכים הישנים לקולקציה החדשה. כדי למנוע נקודות חמות, רצוי להימנע מהקלדה של משימות באצווה למזהי מסמכים רצופים. כשמשימת האצווה תסתיים, תוכלו לקרוא רק מהאוסף החדש.
שיפור של האסטרטגיה הזו הוא העברה של קבוצות קטנות של משתמשים בכל פעם. מוסיפים שדה למסמך המשתמש כדי לעקוב אחרי סטטוס ההעברה של המשתמש. בחירת קבוצה של משתמשים להעברה על סמך גיבוב של מזהה המשתמש. תוכלו להשתמש במשימה באצווה כדי להעביר מסמכים עבור קבוצת המשתמשים הזו, ולהשתמש בקריאות מקבילות למשתמשים באמצע ההעברה.
חשוב לזכור שלא ניתן לבצע בקלות חזרה לאחור, אלא אם מבצעים כתיבת כפולה של הישות הישנה ושל הישות החדשה במהלך שלב ההעברה. הפעולה הזו תגדיל את העלויות של Cloud Firestore.
פרטיות
- הימנעו מאחסון מידע רגיש במזהה פרויקט ב-Cloud. יכול להיות שמזהה הפרויקט ב-Cloud יישמר גם אחרי שהפרויקט יסתיים.
- כחלק משיטות מומלצות לתאימות נתונים, מומלץ לא לאחסן מידע אישי רגיש בשמות של מסמכים ובשמות של שדות במסמכים.
מניעת גישה לא מורשית
מניעת פעולות לא מורשות במסד הנתונים שלכם באמצעות Cloud Firestore Security Rules. לדוגמה, שימוש בכללים יכול למנוע תרחיש שבו משתמש זדוני מוריד שוב ושוב את כל מסד הנתונים.
מידע נוסף על שימוש ב-Cloud Firestore Security Rules