
סובלנות תקלות וזמינות גבוהה הם נושאים גדולים, לכן נקדיש מאמרים נפרדים ל-RabbitMQ ול-Kafka. מאמר זה עוסק ב-RabbitMQ, והמאמר הבא עוסק בקפקא, בהשוואה ל-RabbitMQ. זה מאמר ארוך, אז תרגיש בנוח.
הבה נבחן את אסטרטגיות סובלנות התקלות, העקביות והזמינות הגבוהה (HA) ואת הפשרות שכל אסטרטגיה עושה. RabbitMQ יכול לרוץ על אשכול של צמתים - ולאחר מכן מסווג כמערכת מבוזרת. כשמדובר במערכות מבוזרות, אנחנו מדברים לרוב על עקביות וזמינות.
מושגים אלו מתארים כיצד מערכת מתנהגת כאשר היא נכשלת. כשל בחיבור רשת, כשל בשרת, כשל בכונן הקשיח, חוסר זמינות זמנית של השרת עקב איסוף אשפה, אובדן מנות או האטה בחיבור לרשת. כל זה יכול להוביל לאובדן נתונים או התנגשויות. מסתבר שלמעשה בלתי אפשרי להקים מערכת שהיא גם עקבית לחלוטין (ללא אובדן נתונים, ללא סטיית נתונים) וגם זמינה (תקבל קריאה וכתיבה) לכל תרחישי הכשל.
נראה שהעקביות והזמינות נמצאות בקצוות מנוגדים של הספקטרום, ואתה צריך לבחור באיזו דרך לייעל. החדשות הטובות הן שעם RabbitMQ הבחירה הזו אפשרית. יש לך סוג של מנופים "חנונים" כדי להעביר את האיזון לעבר עקביות רבה יותר או נגישות רבה יותר.
נקדיש תשומת לב מיוחדת לאילו תצורות מובילות לאובדן נתונים עקב רשומות מאושרות. יש שרשרת של אחריות בין מפרסמים, מתווכים וצרכנים. ברגע שהמסר מועבר למתווך, תפקידו לא לאבד את ההודעה. כאשר המתווך מאשר את קבלת ההודעה על ידי המפרסם, אנו לא מצפים שהיא תאבד. אבל נראה שזה באמת יכול לקרות בהתאם לתצורת המתווך והמוציא לאור שלך.
פרימיטיבים של חוסן צומת בודד
עמידה בתור/ניתוב
ישנם שני סוגים של תורים ב-RabbitMQ: עמיד ולא עמיד. כל התורים נשמרים במסד הנתונים של Mnesia. תורים עמידים מתפרסמים מחדש בעת הפעלת הצומת ובכך שורדים הפעלה מחדש, קריסות מערכת או קריסות שרת (כל עוד הנתונים נמשכים). זה אומר שכל עוד אתה מצהיר על הניתוב (החלפה) והתור כעמידים, תשתית התור/ניתוב תחזור לאינטרנט.
תורים נדיפים וניתוב מוסרים כאשר הצומת מופעל מחדש.
הודעות מתמשכות
זה שתור עמיד לא אומר שכל ההודעות שלו ישרדו הפעלה מחדש של צומת. רק הודעות שהוגדרו על ידי המפרסם בתור יציב (מַתְמִיד). הודעות מתמשכות אכן יוצרות עומס נוסף על המתווך, אבל אם אובדן הודעות אינו מקובל, אין אפשרות אחרת.

אורז. 1. מטריצת קיימות
מקבץ עם שיקוף תור
כדי לשרוד אובדן של מתווך, אנחנו צריכים יתירות. אנו יכולים לשלב מספר צמתים של RabbitMQ לתוך אשכול, ולאחר מכן להוסיף יתירות נוספת על ידי שכפול תורים בין מספר צמתים. בדרך זו, אם צומת אחד נכשל, אנחנו לא מאבדים נתונים ונשארים זמינים.
שיקוף תור:
- תור ראשי אחד (מאסטר), שמקבל את כל פקודות הכתיבה והקריאה
- מראה אחת או יותר שמקבלת את כל ההודעות והמטא נתונים מהתור הראשי. המראות הללו אינן שם עבור קנה מידה, אלא אך ורק עבור יתירות.

אורז. 2. שיקוף תור
שיקוף נקבע על ידי המדיניות המתאימה. בו ניתן לבחור את מקדם השכפול ואפילו את הצמתים עליהם אמור להיות ממוקם התור. דוגמאות:
ha-mode: allha-mode: exactly, ha-params: 2(מאסטר אחד ומראה אחת)ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2
אישור מפרסם
כדי להשיג הקלטה עקבית, נדרשים אישורי מפרסם. בלעדיהם, קיים סיכון לאיבוד הודעות. אישור נשלח למפרסם לאחר כתיבת ההודעה לדיסק. RabbitMQ כותב הודעות לדיסק לא עם הקבלה, אלא על בסיס תקופתי, באזור של כמה מאות אלפיות שניות. כאשר תור משוקף, אישור נשלח רק לאחר שכל המראות כתבו גם את העותק של ההודעה לדיסק. המשמעות היא ששימוש באישורים מוסיף זמן אחזור, אבל אם אבטחת מידע חשובה, אז הם נחוצים.
תור כשל
כאשר ברוקר עוזב או קורס, כל מובילי התורים (מאסטרים) באותו צומת קורסים יחד איתו. לאחר מכן, האשכול בוחר את המראה הישנה ביותר של כל מאסטר ומקדם אותה כמאסטר החדש.

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

אורז. 4. ברוקר 3 נכשל, מה שגורם לתור C להיכשל
הברוקר 1 הבא נופל! נשאר לנו רק מתווך אחד. מראה תור B מקודם למאסטר.

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

אורז. 6. ברוקר 1 חוזר לשירות
ברוקר 3 חזר לאינטרנט, אז התורים A ו-B מקבלים בחזרה את המראות שנוצרו עליו כדי לעמוד במדיניות ה-HA שלהם. אבל עכשיו כל התורים הראשיים נמצאים על צומת אחד! זה לא אידיאלי, חלוקה שווה בין צמתים טובה יותר. למרבה הצער, אין כאן הרבה אפשרויות לאיזון מחדש של מאסטרים. נחזור לנושא זה מאוחר יותר כי עלינו לבחון תחילה את סנכרון התורים.

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

אורז. 8. שני תורים עם מצבי סנכרון שונים
עכשיו אנחנו מפסידים את ברוקר 3.

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

אורז. 10. המראה החדשה של תור א' מקבלת את כל ההודעות הקיימות, אבל המראה החדשה של תור ב' לא.
עשר הודעות נוספות מגיעות בשני התורים. לאחר מכן ברוקר 2 קורס ותור A מתגלגל חזרה למראה הישנה ביותר, שנמצאת בברוקר 1. אין אובדן נתונים כאשר הוא נכשל. בתור B, יש עשרים הודעות במאסטר ורק עשר במראה מכיוון שהתור הזה מעולם לא שיכפל את עשר ההודעות המקוריות.

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

אורז. 12. תור A מתגלגל חזרה לברוקר 3 מבלי לאבד הודעות. תור B חוזר לברוקר 3 עם עשר הודעות אבודות
אנחנו יכולים גם להתקין ha-promote-on-failure לתוך משמעות when-synced. במקרה זה, במקום לחזור למראה, התור ימתין עד שהברוקר 1 עם הנתונים שלו יחזור למצב מקוון. לאחר שהוא חוזר, התור הראשי חוזר לברוקר 1 ללא כל אובדן נתונים. זמינות מוקרבת למען אבטחת מידע. אבל זהו מצב מסוכן שיכול אפילו להוביל לאובדן נתונים מוחלט, אותו נבחן בקרוב.

אורז. 13. תור B נשאר לא זמין לאחר איבוד ברוקר 1
אתה עשוי לשאול, "האם עדיף לעולם לא להשתמש בסנכרון אוטומטי?" התשובה היא שסנכרון הוא פעולת חסימה. במהלך הסנכרון, התור הראשי לא יכול לבצע שום פעולות קריאה או כתיבה!
בואו נסתכל על דוגמה. עכשיו יש לנו תורים ארוכים מאוד. איך הם יכולים לגדול לגודל כזה? בשל כמה סיבות:
- לא נעשה שימוש פעיל בתורים
- אלו תורים מהירים, וכרגע הצרכנים איטיים
- זה תורים במהירות גבוהה, הייתה תקלה והצרכנים מדביקים את הקצב

אורז. 14. שני תורים גדולים עם מצבי סנכרון שונים
עכשיו ברוקר 3 נופל.

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

אורז. 16. התור נשאר לא זמין במהלך הסנכרון
לאחר שעתיים, גם תור A הופך לזמין ויכול להתחיל לקבל שוב קריאה וכתיבה.
עדכונים
התנהגות חסימה זו במהלך הסנכרון מקשה על עדכון אשכולות עם תורים גדולים מאוד. בשלב מסוים, צריך להפעיל מחדש את הצומת הראשי, כלומר לעבור למראה או להשבית את התור בזמן שדרוג השרת. אם נבחר לעבור, נאבד הודעות אם המראות לא יהיו מסונכרנות. כברירת מחדל, במהלך הפסקת ברוקר, לא מבוצע מעבר כשל למראה לא מסונכרנת. זה אומר שברגע שהברוקר חוזר, אנחנו לא מאבדים שום הודעה, הנזק היחיד היה תור פשוט. כללי התנהגות כאשר מתווך מנותק נקבעים במדיניות ha-promote-on-shutdown. אתה יכול להגדיר אחד משני ערכים:
always= מעבר למראות לא מסונכרנות מופעלwhen-synced= מעבר למראה מסונכרנת בלבד, אחרת התור הופך לבלתי קריא ולא ניתן לכתיבה. התור חוזר לשירות ברגע שהברוקר חוזר
כך או אחרת, עם תורים גדולים אתה צריך לבחור בין אובדן נתונים לבין חוסר זמינות.
כאשר זמינות משפרת את אבטחת הנתונים
יש עוד סיבוך אחד שצריך לקחת בחשבון לפני קבלת החלטה. בעוד סנכרון אוטומטי עדיף על יתירות, כיצד הוא משפיע על אבטחת הנתונים? כמובן, עם יתירות טובה יותר, RabbitMQ נוטה פחות לאבד הודעות קיימות, אבל מה לגבי הודעות חדשות מבעלי אתרים?
כאן אתה צריך לשקול את הדברים הבאים:
- האם המוציא לאור יכול פשוט להחזיר שגיאה ולבקש מהשירות במעלה הזרם או למשתמש לנסות שוב מאוחר יותר?
- האם המוציא לאור יכול לשמור את ההודעה באופן מקומי או במסד נתונים כדי לנסות שוב מאוחר יותר?
אם המפרסם יכול רק למחוק את ההודעה, אז למעשה, שיפור הנגישות משפר גם את אבטחת הנתונים.
לפיכך, יש לחפש איזון, והפתרון תלוי במצב הספציפי.
בעיות עם ha-promote-on-failure=when-Sync
רעיון הא-לקדם-על-כישלון= כאשר מסונכרן היא שאנו מונעים מעבר למראה לא מסונכרנת ובכך נמנעים מאובדן נתונים. התור נשאר בלתי קריא או ניתן לכתיבה. במקום זאת, אנו מנסים לשחזר את המתווך שקרס עם הנתונים שלו ללא פגע, כך שהוא יוכל לחזור לתפקד כמאסטר ללא אובדן נתונים.
אבל (וזה אבל גדול) אם המתווך איבד את הנתונים שלו, אז יש לנו בעיה גדולה: התור אבוד! כל הנתונים נעלמו! גם אם יש לך מראות שמדביקות בעיקר את התור הראשי, גם המראות האלה נמחקות.
כדי להוסיף מחדש צומת עם אותו שם, אנו אומרים לאשכול לשכוח את הצומת האבוד (עם הפקודה rabbitmqctl forget_cluster_node) והתחל מתווך חדש עם אותו שם מארח. בעוד שהאשכול זוכר את הצומת האבוד, הוא זוכר את התור הישן ואת המראות הלא מסונכרנות. כשאומרים לאשכול לשכוח צומת יתום, גם התור הזה נשכח. עכשיו אנחנו צריכים להכריז על זה מחדש. איבדנו את כל הנתונים, למרות שהיו לנו מראות עם סט חלקי של נתונים. עדיף לעבור למראה לא מסונכרנת!
לכן, סנכרון ידני (ואי סנכרון) בשילוב עם ha-promote-on-failure=when-synced, לדעתי, די מסוכן. המסמכים טוענים שהאפשרות הזו קיימת לאבטחת מידע, אבל זו סכין פיפיות.
מאסטר איזון מחדש
כפי שהובטח, אנו חוזרים לבעיית הצטברות כל המאסטרים על צמתים אחד או כמה. זה יכול לקרות אפילו כתוצאה מעדכון אשכול מתגלגל. באשכול של שלושה צמתים, כל תורי המאסטר יצטברו בצמת אחד או שניים.
איזון מחדש של מאסטרים יכול להיות בעייתי משתי סיבות:
- אין כלים טובים לבצע איזון מחדש
- סנכרון תור
יש צד שלישי לאיזון מחדש , שאינו נתמך רשמית. לגבי תוספים של צד שלישי במדריך של RabbitMQ : "התוסף מספק כמה כלי תצורה ודיווח נוספים, אך אינו נתמך או מאומת על ידי צוות RabbitMQ. השימוש על אחריותך בלבד."
יש עוד טריק להעביר את התור הראשי דרך מדיניות HA. המדריך מזכיר לזה. זה עובד ככה:
- מסיר את כל המראות באמצעות מדיניות זמנית בעלת עדיפות גבוהה יותר ממדיניות ה-HA הקיימת.
- משנה את המדיניות הזמנית של HA לשימוש במצב צומת, תוך ציון הצומת שאליו יש להעביר את התור הראשי.
- מסנכרן את התור להעברת דחיפה.
- לאחר השלמת ההגירה, מוחק את המדיניות הזמנית. מדיניות ה-HA הראשונית נכנסת לתוקף ונוצר המספר הנדרש של מראות.
החיסרון הוא שייתכן שגישה זו לא תעבוד אם יש לך תורים גדולים או דרישות יתירות קפדניות.
עכשיו בואו נראה איך אשכולות RabbitMQ עובדים עם מחיצות רשת.
אובדן קישוריות
הצמתים של מערכת מבוזרת מחוברים באמצעות קישורי רשת, וקישורי רשת יכולים ויתנתקו. תדירות ההפסקות תלויה בתשתית המקומית או באמינות הענן הנבחר. בכל מקרה, מערכות מבוזרות חייבות להיות מסוגלות להתמודד איתן. שוב יש לנו בחירה בין זמינות לעקביות, ושוב החדשות הטובות הן ש-RabbitMQ מספקת את שתי האפשרויות (רק לא בו זמנית).
עם RabbitMQ יש לנו שתי אפשרויות עיקריות:
- אפשר חלוקה לוגית (מוח מפוצל). זה מבטיח זמינות, אך עלול לגרום לאובדן נתונים.
- השבת הפרדה לוגית. עלול לגרום לאובדן זמינות לטווח קצר בהתאם לאופן שבו לקוחות מתחברים לאשכול. יכול גם להוביל לאי-זמינות מוחלטת באשכול שני צמתים.
אבל מהי הפרדה לוגית? זה כאשר אשכול מתפצל לשניים עקב אובדן חיבורי רשת. בכל צד, המראות מקודמות למאסטר, כך שבסופו של דבר יש כמה מאסטרים בכל תור.

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

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

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

אורז. 20. המנהלן משבית את ברוקר 3.

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

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

אורז. 23. ברוקר 3 עוצר, מנתק את כל הלקוחות ודוחה בקשות חיבור.
ברגע שהקישוריות משוחזרת, היא חוזרת לאשכול.
בואו נסתכל על דוגמה נוספת שבה התור הראשי נמצא בברוקר 3.

אורז. 24. תור ראשי בברוקר 3.
ואז מתרחש אותו אובדן קישוריות. ברוקר 3 עוצר כי הוא בצד הקטן יותר. בצד השני, הצמתים רואים שהברוקר 3 נפל, אז המראה הישנה יותר מברוקרים 1 ו-2 מקודמת למאסטר.

אורז. 25. מעבר לברוקר 2 אם ברוקר 3 אינו זמין.
כאשר הקישוריות תשוחזר, Broker 3 יצטרף לאשכול.

אורז. 26. האשכול חזר לפעולה רגילה.
מה שחשוב להבין כאן הוא שאנחנו מקבלים עקביות, אבל אנחנו יכולים גם להשיג זמינות, אם נעביר בהצלחה לקוחות לרוב המדור. עבור רוב המצבים, אני אישית הייתי בוחר במצב Pause Minority, אבל זה באמת תלוי במקרה הפרטני.
כדי להבטיח זמינות, חשוב לוודא שלקוחות מתחברים בהצלחה למארח. בואו נסתכל על האפשרויות שלנו.
הבטחת קישוריות לקוחות
יש לנו מספר אפשרויות כיצד להפנות לקוחות לחלק העיקרי של האשכול או לצמתים עובדים (לאחר שצומת אחד נכשל) לאחר אובדן קישוריות. ראשית, בואו נזכור שתור מסוים מתארח בצומת ספציפי, אך ניתוב ומדיניות משוכפלים בכל הצמתים. לקוחות יכולים להתחבר לכל צומת, וניתוב פנימי יכוון אותם לאן שהם צריכים להגיע. אבל כאשר צומת מושעה, הוא דוחה חיבורים, כך שהלקוחות חייבים להתחבר לצומת אחר. אם הצומת נופל, הוא יכול לעשות מעט.
האפשרויות שלנו:
- הגישה לאשכול מתבצעת באמצעות מאזן עומסים שפשוט עובר דרך הצמתים ולקוחות מנסים להתחבר מחדש עד להצליח. אם צומת מושבת או מושעה, ניסיונות להתחבר לצומת זה ייכשלו, אך הניסיונות הבאים יעברו לשרתים אחרים (באופן סיבובי). זה מתאים לאובדן קישוריות לטווח קצר או לשרת מושבת שיוחזר במהירות.
- גש לאשכול דרך מאזן עומסים והסר צמתים מושעים/נכשלים מהרשימה ברגע שהם מזוהים. אם נעשה זאת במהירות, ואם לקוחות יוכלו לנסות שוב את החיבור, נשיג זמינות מתמדת.
- תן לכל לקוח רשימה של כל הצמתים, והלקוח בוחר באקראי אחד מהם בעת החיבור. אם הוא מקבל שגיאה בעת ניסיון להתחבר, הוא עובר לצומת הבא ברשימה עד שהוא מתחבר.
- הסר תעבורה מצומת כושל/מושעה באמצעות DNS. זה נעשה באמצעות TTL קטן.
ממצאים
לאשכול RabbitMQ יש יתרונות וחסרונות. החסרונות החמורים ביותר הם כי:
- כאשר מצטרפים לאשכול, צמתים משליכים את הנתונים שלהם;
- חסימת סנכרון גורמת לתור להיות בלתי זמין.
כל ההחלטות הקשות נובעות משני המאפיינים האדריכליים הללו. אם RabbitMQ יוכל לשמור נתונים כאשר האשכול יתחבר מחדש, אז הסנכרון יהיה מהיר יותר. אם זה היה מסוגל לסנכרון לא חוסם, זה היה תומך טוב יותר בתורים גדולים. תיקון שתי הבעיות הללו ישפר מאוד את הביצועים של RabbitMQ כטכנולוגיית מסרים עמידה לתקלות וזמינה ביותר. הייתי מהסס להמליץ על RabbitMQ עם אשכולות במצבים הבאים:
- רשת לא אמינה.
- אחסון לא אמין.
- תורים ארוכים מאוד.
כשמדובר בהגדרות זמינות גבוהה, שקול את הדברים הבאים:
ha-promote-on-failure=alwaysha-sync-mode=manualcluster_partition_handling=ignore(אוautoheal)- הודעות מתמשכות
- להבטיח שלקוחות מתחברים לצומת הפעיל כאשר צומת מסוים נכשל
למען עקביות (אבטחת נתונים), שקול את ההגדרות הבאות:
- מפרסמים מאשרים ותודות ידניות בצד הצרכני
ha-promote-on-failure=when-synced, אם המוציאים לאור יוכלו לנסות שוב מאוחר יותר ואם יש לך אחסון אמין מאוד! אחרת לשים=always.ha-sync-mode=automatic(אך עבור תורים גדולים שאינם פעילים עשוי להידרש מצב ידני; שקול גם אם חוסר זמינות יגרום לאיבוד הודעות)- השהה את מצב מיעוטים
- הודעות מתמשכות
עדיין לא כיסינו את כל הנושאים של סובלנות תקלות וזמינות גבוהה; לדוגמה, כיצד לבצע בצורה מאובטחת הליכים ניהוליים (כגון עדכונים מתגלגלים). אנחנו צריכים לדבר גם על הפדרציה והתוסף Shovel.
אם פספסתי עוד משהו, אנא הודע לי.
ראה גם שלי , שבו אני מבצע הרס באשכול RabbitMQ באמצעות Docker ו-Blockade כדי לבדוק כמה מתרחישי אובדן ההודעות המתוארים במאמר זה.
מאמרים קודמים בסדרה:
מס' 1 -
מס' 2 -
מס' 3 -
מקור: www.habr.com
