התכונה 'סדר ההודעות' ב-Pub/Sub מאפשרת לקבל הודעות בלקוחות של הנמענים בסדר שבו הן פורסמו על ידי הלקוחות של המפרסמים.
לדוגמה, נניח שלקוח מפרסם באזור מסוים את ההודעות 1, 2 ו-3 לפי הסדר. כשמשתמשים בסדר הודעות, לקוח המנוי מקבל את ההודעות שפורסמו באותו סדר. כדי שההודעות יימסרו לפי הסדר, לקוח ההוצאה לאור צריך לפרסם את ההודעות באותו אזור. עם זאת, המנויים יכולים להתחבר לכל אזור, וההבטחה לגבי סדר ההודעות עדיין תקפה.
התכונה 'סדר ההודעות' שימושית בתרחישים כמו תיעוד שינויים במסד נתונים, מעקב אחר סשנים של משתמשים ואפליקציות סטרימינג שבהם חשוב לשמור על הכרונולוגיה של האירועים.
בדף הזה מוסבר המושג 'סדר ההודעות' ואיך מגדירים את לקוחות המנויים לקבלת הודעות לפי הסדר. כדי להגדיר את לקוחות ה-Publisher כך שיסדרו את ההודעות, אפשר לעיין במאמר בנושא שימוש במפתחות סדר כדי לפרסם הודעה.
סקירה כללית על סדר ההודעות
הסדר ב-Pub/Sub נקבע לפי:
מפתח להזמנה. מפתח הזמנה הוא מחרוזת שמזהה הודעות קשורות שצריך לסדר. דוגמאות למפתחות הזמנה כוללות מזהי לקוחות או את המפתח הראשי של שורה במסד נתונים. אורך מפתח ההזמנה יכול להיות עד 1KB.
כדי להשיג סדר הודעות, צריך להגדיר את אותו מפתח סדר בכל ההודעות הקשורות שצריכות להתקבל בסדר מסוים. בנוסף, צריך לפרסם את כל ההודעות עם אותו מפתח הזמנה באותו אזור. מידע נוסף זמין במאמר שימוש במפתחות להזמנת פרסום של הודעה.
הודעות עם מפתח סידור ריק לא מסודרות.
מפעילים את האפשרות 'סדר ההודעות'. כדי לקבל את ההודעות לפי הסדר, צריך להפעיל את האפשרות 'סידור הודעות' במינוי. מידע נוסף זמין במאמר הפעלת סידור הודעות.
אם לא מפעילים את האפשרות 'סדר ההודעות', המינוי מקבל הודעות ללא סדר צפוי. לדוגמה, נניח שהמינויים A ו-B משויכים שניהם לאותו נושא T, וההזמנה מופעלת במינוי A אבל לא במינוי B. למרות ששני המינויים מקבלים את אותה קבוצת הודעות מהנושא T, הסדר נשמר רק במינוי A.
קצב העברת הנתונים של הפרסום בכל מפתח הזמנה מוגבל ל-1MBps. התפוקה של כל מפתחות ההזמנה בנושא מוגבלת למכסת הזמינות באזור הפרסום. אפשר להגדיל את המגבלה הזו לכמה גיגה-ביט לשנייה.
באופן כללי, אם הפתרון שלכם דורש מלקוחות של בעלי תוכן דיגיטלי לשלוח הודעות מסודרות ולא מסודרות, כדאי ליצור נושאים נפרדים – אחד להודעות מסודרות ואחד להודעות לא מסודרות.
שיקולים לשימוש בהעברת הודעות לפי סדר
בהמשך מופיע מידע חשוב לגבי אופן הפעולה של הודעות מסודרות ב-Pub/Sub:
עוצמה (cardinality). מפתח סידור לא שווה למחיצה במערכת הודעות מבוססת-מחיצות, כי מפתחות סידור צפויים להיות בעלי קרדינליות גבוהה בהרבה ממחיצות.
סדר בתוך מפתח: הודעות שמתפרסמות עם אותו מפתח סדר צפויות להתקבל לפי הסדר. נניח שאתם מפרסמים את ההודעות 1, 2 ו-3 באמצעות מפתח ההזמנה א'. אם ההזמנה מופעלת, צפוי שפריט 1 יימסר לפני פריט 2, ופריט 2 יימסר לפני פריט 3.
סדר בין מפתחות: לא צפוי שהודעות שפורסמו עם מפתחות סדר שונים יתקבלו לפי הסדר. נניח שיש לכם מפתחות הזמנה A ו-B. אם משתמשים במפתח A, ההודעות 1 ו-2 מתפרסמות לפי הסדר. כדי להזמין את מפתח B, ההודעות 3 ו-4 מתפרסמות לפי הסדר. עם זאת, יכול להיות שהודעה 1 תגיע לפני הודעה 4 או אחריה.
מסירה חוזרת של הודעות: שירות Pub/Sub מספק כל הודעה לפחות פעם אחת, ולכן יכול להיות שהוא יספק הודעות מחדש. שליחה מחדש של הודעה גורמת לשליחה מחדש של כל ההודעות הבאות עבור המפתח הזה, גם אם הן אושרו. נניח שלקוח מנוי מקבל את ההודעות 1, 2 ו-3 עבור מפתח סדר ספציפי. אם הודעה 2 נמסרת מחדש (כי תאריך היעד לאישור פג או שהאישור במקרה הטוב לא נשמר ב-Pub/Sub), גם הודעה 3 נמסרת מחדש. אם גם ההזמנה של ההודעות וגם נושא להודעות ללא מוצא מופעלים במינוי, יכול להיות שההתנהגות הזו לא תתרחש, כי Pub/Sub מעביר הודעות לנושאים להודעות ללא מוצא על בסיס המקסימום המאמץ.
עיכובים באישור ונושאים של הודעות שלא נמסרו: הודעות שלא אושרו עבור מפתח סדר נתון עלולות לעכב את המסירה של הודעות עבור מפתחות סדר אחרים, במיוחד במהלך הפעלה מחדש של השרת או שינויים בתנועה. כדי לשמור על הסדר באירועים כאלה, חשוב לאשר את קבלת כל ההודעות בזמן. אם אי אפשר לשלוח אישור בזמן, כדאי להשתמש בנושא להודעות ללא מוצא כדי למנוע החזקה של הודעות ללא הגבלת זמן. חשוב לדעת שהסדר לא נשמר כשכותבים הודעות לנושא להודעות ללא מוצא.
הודעות שקשורות לאותו מפתח (לקוחות streamingPull): הודעות שקשורות לאותו מפתח בדרך כלל מועברות לאותו לקוח מנוי של streamingPull. הזיקה צפויה כשהודעות ממתינות למפתח הזמנה ללקוח מנוי ספציפי. אם אין הודעות בהמתנה, יכול להיות שהזיקה תשתנה לצורך איזון עומסים או ניתוקים של לקוחות.
כדי להבטיח עיבוד חלק גם במקרה של שינויים פוטנציאליים בזיקה, חשוב לתכנן את אפליקציית streamingPull כך שהיא תוכל לטפל בהודעות בכל לקוח עבור מפתח הזמנה נתון.
שילוב עם Dataflow: אל תפעילו את האפשרות 'הזמנת הודעות' למינויים כשמגדירים את Dataflow עם Pub/Sub. ל-Dataflow יש מנגנון משלו משלו לסידור כל ההודעות, כדי להבטיח סדר כרונולוגי של כל ההודעות כחלק מפעולות של חלונות. שיטת ההזמנה הזו שונה מהגישה של Pub/Sub שמבוססת על מפתח הזמנה. שימוש במפתחות הזמנה עם Dataflow עשוי להפחית את הביצועים של צינור עיבוד הנתונים.
התאמה אוטומטית לעומס: התכונה 'שליחה מסודרת' ב-Pub/Sub יכולה להתרחב למיליארדי מפתחות סידור. מספר גדול יותר של מפתחות הזמנה מאפשר מסירה מקבילה יותר למנויים, כי ההזמנה חלה על כל ההודעות עם אותו מפתח הזמנה.
השפעה על הביצועים: יש כמה חסרונות לשימוש באפשרות של משלוח לפי סדר. בהשוואה למסירה לא מסודרת, מסירה מסודרת מקטינה את הזמינות של פרסום ומגדילה את זמן האחזור של מסירת הודעות מקצה לקצה. במקרה של מסירה מסודרת, המעבר לגיבוי דורש תיאום כדי להבטיח שההודעות ייכתבו וייקראו בסדר הנכון.
מפתח הזמנה: כשמשתמשים בהזמנת הודעות, כל ההודעות עם אותו מפתח הזמנה נשלחות ללקוח המנוי בסדר שבו הן מתקבלות בשירות. הקריאה החוזרת של המשתמש לא מופעלת עד שהקריאה החוזרת מסתיימת עבור ההודעה הקודמת. התפוקה המקסימלית של הודעות שמשתפות את אותו מפתח סדר כשמספקים אותן למנויים לא מוגבלת על ידי Pub/Sub , אלא על ידי מהירות העיבוד של לקוח המנוי. מקש חם נוצר כשמצטבר בקלוג על מקש הזמנה ספציפי, כי מספר ההודעות שנוצרות בשנייה חורג ממספר ההודעות שהמנוי יכול לעבד בשנייה. כדי לצמצם את השימוש במקשים חמים, כדאי להשתמש במקשים הכי מפורטים שאפשר ולצמצם את זמן העיבוד של כל הודעה. אפשר גם לעקוב אחרי המדד
subscription/oldest_unacked_message_ageכדי לראות אם הערך שלו עולה, כי זה יכול להצביע על מקש קיצור.
מידע נוסף על השימוש בסדר ההודעות זמין במאמרים הבאים בנושא שיטות מומלצות:
התנהגות של לקוח שרשום כמנוי בנוגע לסדר ההודעות
לקוחות של מינויים מקבלים הודעות לפי הסדר שבו הן פורסמו באזור מסוים. ב-Pub/Sub יש דרכים שונות לקבלת הודעות, כמו לקוחות של מנויים שמחוברים למינויים מסוג pull ו-push. ספריות הלקוח משתמשות ב-streamingPull (למעט PHP).
מידע נוסף על סוגי המינויים האלה זמין במאמר בחירת סוג מינוי.
בקטעים הבאים מוסבר מה המשמעות של קבלת הודעות לפי הסדר לכל סוג של לקוח מנוי.
לקוחות של מנויים ב-StreamingPull
כשמשתמשים בספריות הלקוח עם streamingPull, צריך לציין קריאה חוזרת (callback) של משתמש שמופעלת בכל פעם שהודעה מתקבלת על ידי לקוח של מנוי. בספריות לקוח, לכל מפתח הזמנה נתון, הקריאה החוזרת מופעלת עד הסיום בהודעות בסדר הנכון. אם ההודעות מאושרות במהלך הקריאה החוזרת, כל החישובים לגבי ההודעה מתבצעים לפי הסדר. עם זאת, אם פונקציית הקריאה החוזרת של המשתמש מתזמנת עבודה אסינכרונית אחרת בהודעות, לקוח המנוי צריך לוודא שהעבודה האסינכרונית מתבצעת לפי הסדר. אפשרות אחת היא להוסיף הודעות לתור עבודה מקומי שמעובד לפי הסדר.
שליפה של לקוחות מנויים
ללקוחות של מינויים שמחוברים למינויים מסוג pull, התכונה 'סדר ההודעות ב-Pub/Sub' תומכת באפשרויות הבאות:
כל ההודעות של מפתח הזמנה ב-PullResponse מסודרות בסדר הנכון ברשימה.
בכל פעם יכולה להיות רק קבוצה אחת של הודעות בהמתנה למפתח סידור.
הדרישה שאפשר להשאיר רק אצווה אחת של הודעות בהמתנה בכל פעם נחוצה כדי לשמור על מסירה מסודרת, כי שירות Pub/Sub לא יכול להבטיח את ההצלחה או את זמן האחזור של התגובה שהוא שולח לבקשת משיכה של מנוי.
לקוחות של מנויי דחיפה
ההגבלות על שליחת נתונים (push) מחמירות יותר מאלה על משיכת נתונים (pull). במינוי דחיפה, Pub/Sub תומך רק בהודעה אחת שלא נמסרה לכל מפתח הזמנה בכל פעם. כל הודעה נשלחת לנקודת קצה של Push כבקשה נפרדת. לכן, שליחת הבקשות במקביל תגרום לאותה בעיה כמו שליחת כמה קבוצות של הודעות עם אותו מפתח הזמנה למנויים בו-זמנית. יכול להיות שהרשמה לקבלת עדכונים לא תהיה בחירה טובה לנושאים שבהם מתפרסמות הודעות לעיתים קרובות עם אותו מפתח סידור, או במקרים שבהם זמן האחזור חשוב במיוחד.
ייצוא של לקוחות מנויים
ייצוא מינויים תומך בהודעות מסודרות. במינויים ל-BigQuery, הודעות עם אותו מפתח סדר נכתבות לטבלה ב-BigQuery שלהן לפי הסדר. במינויים ל-Cloud Storage, יכול להיות שלא כל ההודעות עם אותו מפתח סדר ייכתבו לאותו קובץ. בתוך אותו קובץ, ההודעות שמקושרות למפתח הזמנה מופיעות לפי הסדר. אם ההודעות מפוזרות על פני כמה קבצים, יכול להיות שהודעות מאוחרות יותר עם מפתח הזמנה יופיעו בקובץ עם שם שכולל חותמת זמן מוקדמת יותר מחותמת הזמן בשם של הקובץ עם ההודעות המוקדמות יותר.
הפעלת האפשרות להזמין בהודעות
כדי לקבל את ההודעות לפי הסדר, צריך להגדיר את מאפיין סדר ההודעות במינוי שממנו מקבלים הודעות. קבלת הודעות לפי הסדר עשויה להגדיל את זמן האחזור. אי אפשר לשנות את מאפיין הסדר של ההודעות אחרי שיוצרים מינוי.
אפשר להגדיר את הנכס של סדר ההודעות כשיוצרים מינוי באמצעות Google Cloud המסוף, Google Cloud CLI או Pub/Sub API.
המסוף
כדי ליצור מינוי עם מאפיין סדר ההודעות, פועלים לפי השלבים הבאים:
- נכנסים לדף Subscriptions במסוף Google Cloud .
לוחצים על יצירת מינוי.
מזינים מזהה מינוי.
בוחרים נושא שרוצים לקבל עליו הודעות.
בקטע Message ordering (סדר ההודעות), בוחרים באפשרות Order messages with an ordering key (סידור ההודעות באמצעות מפתח סידור).
לוחצים על יצירה.
gcloud
כדי ליצור מינוי עם המאפיין של סדר ההודעות, משתמשים בפקודה gcloud pubsub subscriptions
create ובדגל --enable-message-ordering:
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --enable-message-ordering
מחליפים את SUBSCRIPTION_ID במזהה המינוי.
אם הבקשה מבוצעת בהצלחה, בשורת הפקודה תוצג הודעת אישור:
Created subscription [SUBSCRIPTION_ID].
REST
כדי ליצור מינוי עם מאפיין סדר ההודעות, שולחים PUTבקשה כמו הבקשה הבאה:
PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID Authorization: Bearer $(gcloud auth application-default print-access-token)
מחליפים את מה שכתוב בשדות הבאים:
- PROJECT_ID: מזהה הפרויקט של הפרויקט עם הנושא
- SUBSCRIPTION_ID: מזהה המינוי
בגוף הבקשה, מציינים את הפרטים הבאים:
{ "topic": TOPIC_ID, "enableMessageOrdering": true, }
מחליפים את TOPIC_ID במזהה של הנושא לצירוף למינוי.
אם הבקשה מצליחה, התשובה היא המינוי בפורמט JSON:
{
"name": projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID,
"topic": projects/PROJECT_ID/topics/TOPIC_ID,
"enableMessageOrdering": true,
}
C++
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של C++ במאמר תחילת העבודה: שימוש בספריות לקוח. מידע נוסף זמין במאמרי העזרה של Pub/Sub C++ API.
C#
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של C# במאמר התחלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub C# API.
המשך
בדוגמה הבאה נעשה שימוש בגרסה הראשית של ספריית הלקוח Go Pub/Sub (v2). אם אתם עדיין משתמשים בספרייה v1, כדאי לעיין במדריך להעברת נתונים ל-v2. כדי לראות רשימה של דוגמאות קוד מגרסה 1, אפשר לעיין ב דוגמאות הקוד שהוצאו משימוש.
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Go במאמר מדריך למתחילים: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Go API.
Java
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Java במאמר תחילת העבודה המהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Java API.
Node.js
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במאמר תחילת העבודה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Node.js API.
Node.js
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במאמר תחילת העבודה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Node.js API.
Python
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Python במאמר מדריך למתחילים: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של ה-API בשפת Python של Pub/Sub.
Ruby
בדוגמה הבאה נעשה שימוש בספריית הלקוח של Ruby Pub/Sub בגרסה 3. אם אתם עדיין משתמשים בספרייה v2, כדאי לעיין במדריך להעברה ל-v3. כדי לראות רשימה של דוגמאות קוד של Ruby v2, אפשר לעיין ב דוגמאות הקוד שהוצאו משימוש.
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Ruby במאמר תחילת העבודה המהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Ruby API.
חלודה
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Rust במאמר מדריך מהיר: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Rust API.
המאמרים הבאים
לקריאת הפוסט בבלוג על משלוח מסודר
כדי להמשיך לפרסם הודעות במקרה של שגיאות שלא ניתן לנסות שוב, אפשר לעיין במאמר בנושא ניסיון חוזר של בקשות עם מפתחות הזמנה.
מעקב אחרי המינוי.
מידע נוסף על פרסום הודעות עם מפתחות הזמנה