PgPool-II: מה נשבר בעת כשל של צומת בסיס נתונים
צומת בסיס הנתונים הראשי מפסיק להגיב ברגע הכי פחות מתאים — למשל בלילה, כשהמהנדס התורן לומד על כך ממערכת ההתראות. באותו רגע היישום מחזיק חיבורים פתוחים אל הצומת שנפל ולא אל הגיבוי: מאגר החיבורים טרם נבנה מחדש, והניתוב טרם הוסב. פעולות כתיבה והזמנות מתחילות ליפול עם שגיאת חיבור, ושאילתות שלא טופלו נערמות בתור.
מכאן מתחילה עבודה ידנית. צריך להעביר את צומת הגיבוי למצב כתיבה, להסב אליו את התעבורה, לוודא שהרפליקה הדביקה את הראשי לפי היומן, ורק אז להחזיר את היישום לפעולה. בזמן שזה קורה, חלק מהשאילתות אובדות ללא תקנה — איש לא ישחזר אותן, מפני שהתור כבר התפזר בין הלקוחות והתפרק ברמת החיבור.
PgPool-II מותקן בין היישום לבסיס הנתונים בדיוק כדי שהתרחיש הזה לא יתפתח באופן ידני. הוא מחזיק מאגר חיבורים משלו, עוקב אחר מצב הצמתים בבדיקות תקופתיות, ובשעת כשל מוציא בעצמו את הצומת שנפל מהניתוב, ואת הגיבוי מעביר למצב כתיבה. היישום ממשיך לקבל חיבור מהמאגר — עבור השירות משתנה כתובת היעד, ולא עצם זמינות בסיס הנתונים.
אך עצם נוכחותו של PgPool-II בארכיטקטורה אינה מסלקת את נקודת הכשל. אם הוא רץ במופע בודד, בלי גיבוי למאגר עצמו ובלי פסקי זמן מכוילים לבדיקה, הכשל פשוט עובר מבסיס הנתונים אליו. להלן נבחן כיצד סוגרים זאת.
מה נותן אשכול בסיסי נתונים עמיד בכשלים
עמידות בכשלים מתגלה לא בעבודה שגרתית, אלא בשניות הראשונות שאחרי התקלה. לכן אנחנו מסתכלים לא על התמיכה המוצהרת ברפליקציה, אלא על ציר הזמן: כמה מהר המאזן מזהה צומת שנפל, מי מסב את התעבורה, ומה רואה היישום באותו רגע.
היישום מתחבר לכתובת אחת, ו-PgPool-II מפזר את החיבורים הנכנסים בין השרתים. בדיקת הזמינות מתבצעת במרווח קצר: לאחר כמה תגובות כושלות הצומת מוצא מהחלוקה, והנותרים מקבלים את התעבורה שלו. אין שגיאות חיבור בצד היישום — משתנה רק הניתוב הפנימי, וזמן ההתאוששות נמדד בשניות במקום טיפול ידני.
מכאן נכנסת הפרדת קריאה וכתיבה: שאילתות שליפה עוברות לרפליקות, ושאילתות משנות — לצומת הראשי. היישום לא יודע על כך, מחרוזת החיבור והקוד נשארים כשהיו. בעומס טיפוסי עד שני שלישים מהפניות עוברות לרפליקות, והצומת הראשי מפסיק להיות נקודה יחידה גם מבחינת עומס וגם מבחינת כשלים.
יכולת החיזוי חשובה כאן יותר מביצועי שיא. הידרדרות של צומת אחד הופכת לאירוע עם תרחיש ידוע: חלק מהשאילתות מאטות, אך השירות נשאר זמין. סוג הכשל „שרת נפל — כל המוצר מושבת” יוצא מרשימת הסיכונים, והתנהגות האשכול נבדקת בתרגילים ולא מתבררת ברגע של תקלה אמיתית.
מצבי הפעולה של PgPool-II ומגבלותיהם
מעגל עמיד בכשלים מבוסס PgPool-II נבנה בכמה דרכים, והמאזן לא תמיד נדרש. השאלה המרכזית היא מה בדיוק נדרש: לעבור כשל של הצומת הראשי, לפזר עומס קריאה, או להחליק פרצים של חיבורים קצרים. מזה תלוי היכן יעמוד PostgreSQL והיכן — שכבת הביניים.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| רפליקציה זורמת של גיבוי חם ללא מאזן | צומת ראשי אחד וגיבוי, קריאה מהגיבוי, הסבה לפי נוהל | אין הסבה אוטומטית בעת כשל; כתובות הצמתים רשומות בתצורת היישום |
| PgPool-II במצב רפליקציית שאילתות | כתובת אחודה ליישום והסבה אוטומטית בעת כשל | ללא מודול watchdog עלול להיווצר פיצול אשכול בעת ניתוק קשר; הקריאה מהרפליקות מפגרת |
| PgPool-II כמאזן חיבורים | הרבה חיבורים קצרים, פרצים, מגבלת חיבורים קשיחה בשרת | אינו מספק עמידות בכשלים — רק החזקה ופיזור מחדש של חיבורים |
| רפליקציה לוגית של טבלאות נבחרות | העברה בין גרסאות מז'וריות, הוצאת חלק מהנתונים למעגל נפרד | אין הסבה אוטומטית, ההשהיה גבוהה יותר, הרכב האובייקטים חייב להיות זהה |
מה לבדוק לפני הבחירה
מצב רפליקציית שאילתות אינו מסיר את מגבלות ה-DBMS עצמה: שאילתות הרגישות לעדכניות הנתונים מנותבות לצומת הראשי, וההרחבות חייבות להיות מותקנות בכל הצמתים. את התאימות בודקים בעומס שיא — השהיית הרפליקציה, ההתנהגות בעת ניתוק ערוץ, והחזרה תקינה של הצומת הראשי הישן לפעולה.
כיצד אנחנו מיישמים אשכול עמיד בכשלים: שלבי העבודה
אשכול בעל זמינות גבוהה נבנה לא „על החי”, אלא לפי רצף שבו כל שלב מאומת בבדיקה. להלן סדר העבודות שלפיו אנחנו מובילים את הפרויקט: מהביקורת ועד למסירה למשמרת של הלקוח. בכל שלב רואים מה כבר נעשה, במה זה אומת ואילו סיכונים נותרו פתוחים.
- ביקורת של הארכיטקטורה הנוכחית ונקודות הכשל. מפרקים את המעגל כפי שהוא: היכן עוברת הכתיבה, מי מחזיק את החיבורים, כיצד בנויה הרפליקציה. מפרטים את נקודות הכשל היחידות — צומת כתיבה אחד, מאזן ללא גיבוי, הסבה ידנית בעת תקלה — ומעריכים את מחיר ההשבתה של כל אחת.
- תכנון המעגל. מקבעים את תפקידי הצמתים (ראשי, גיבוי, צומתי קריאה), את תרשים זרימות הנתונים בין PgPool-II, שרתי בסיסי הנתונים והיישומים, את כללי הניתוב של שאילתות קריאה וכתיבה, ואת מצב פיזור העומס.
- הגדרת הצמתים ובדיקת ההסבה. מקימים את מאגר החיבורים, את הרפליקציה, את בדיקות החיות ואת ההסבה האוטומטית של התפקידים. בנפרד בודקים שהיישום עובר את החלפת הצומת הראשי בלי שינויים בקוד.
- בדיקות כשל בסביבת הניסוי. מוציאים מכלל פעולה בזה אחר זה כל צומת ואת הקשר בין האתרים: בוחנים את זמן ההסבה, את התנהגות תור השאילתות, ואילו טרנזקציות אובדות ואילו לא.
- הרצה תחת עומס. מזרימים פרופיל הקרוב לזה של סביבת הייצור: חיבורי שיא, דוחות כבדים, טרנזקציות ארוכות. בודקים שההסבה נכנסת לחלון המוסכם גם תחת עומס.
- מסירה לתפעול והדרכת המשמרת. מוסרים את התצורות, את תרשים התפקידים והזרימות, ואת הנוהל להסבה ולטיפול בתקלות. מקיימים תרגילים עם המשמרת של הלקוח, כדי שהעברת הצמתים תיעשה לפי הוראות ולא מהזיכרון.
תצורות, תרשימים ונוהלים: תוצרי היישום
היישום נחשב לסגור לא כשהצמתים עלו, אלא כשאצל הלקוח נשאר סט תוצרים שלפיו אפשר לתחזק את המעגל בכוחות עצמו. חלק מהקבצים עוברים למאגר התצורות, וחלק — לבסיס הידע של המשמרת התורנית. להלן מה בדיוק אנחנו מוסרים.
- תצורות עבודה של המעגל עמיד הכשלים — קבצי PgPool-II, צומתי הרפליקציה ומנהל האשכול עם פרמטרים לפרופיל העומס שלכם, ולא תצוגת דמו. נשמרים תחת בקרת גרסאות, כדי שאפשר יהיה להחזיר את ההגדרה לאחור ולא לשחזר אותה מהזיכרון.
- תרשים המעגל — הטופולוגיה המעודכנת: תפקידי הצמתים, נתיבי התעבורה, נקודות הכשל והאופן שבו מתמודדים איתן. מתעדכן בכל שינוי, ולא מתקיים רק בראשו של מהנדס אחד.
- כללי גישה ותפקידים — מטריצת הרשאות על הצמתים, תפקודי המצב של המאזן והניטור; חשבונות נפרדים לתורן ולמערכות האוטומציה, הפרדה בין קריאה לשינוי.
- נוהל הסבה — תרחיש צעד-אחר-צעד להעברת תפקידים מתוכננת ובשעת תקלה, עם זמן צפוי, קריטריונים ל„הגיע הזמן להתערב” וסדר החזרת הצמתים לפעולה.
- הוראות לשחזור צומת — מה לעשות כשהרפליקה מפגרת או נופלת: בדיקת סנכרון, תנאים ליישור פערים בלי יצירה מחדש מלאה, פקודות לתקלות אופייניות.
- יכולת תצפית והתראות על תקלות — סט מדדים (פיגור הרפליקות, מצב הצמתים, שיעור שגיאות הניתוב) עם ספים שמעליהם התורן מקבל אות, ולא לומד על התקלה מתלונות.
- תיעוד התרגילים — זמן ההתאוששות בפועל לפי תוצאות האימונים, ורשימת התיקונים שהוכנסו לנוהל אחרי כל אחד.
מקרה בוחן: זמן ההשבתה בעת כשל בצומת הצטמצם פי כמה
הארכיטקטורה המקורית ונקודות התורפה שלה
שירות עם זרם כתיבה קבוע נשען על צומת ראשי אחד וגיבוי חם, וההסבה בוצעה ידנית בידי המהנדס התורן. כשהצומת הראשי נפל, היישום קיבל שגיאות כתיבה עד שהגיבוי הועלה והתעבורה הופנתה מחדש: זמן ההשבתה הגיע לעשרות דקות, וחלק מהטרנזקציות שלא הושלמו טופלו והורצו שוב ביד.
נקודת התורפה לא הייתה בגיבוי עצמו, אלא בהיעדרו של מכריע אוטומטי — את ההחלטה על המעבר קיבל אדם לפי סימנים עקיפים ובאיחור.
מה שינו ומה הראו המדדים
לפני האשכול הציבו PgPool-II: הוא מחזיק מאגר חיבורים, מתשאל את הצמתים באופן תקופתי, ומיזם בעצמו את ההסבה לגיבוי כשהראשי מפסיק להגיב. שיעור ההסבות האוטומטיות עלה מאפס לכמעט כל הכשלים שהניטור מתעד; טיפול ידני נותר רק בתרחישים של אובדן רשת בין הצמתים, שבהם נדרשת החלטה מודעת.
זמן ההשבתה בעת כשל בצומת הצטמצם פי כמה: ההסבה נכנסת לשניות, והיישום מתחבר מחדש לצומת הראשי החדש במקום להמתין למהנדס. מאגר החיבורים הסיר את העומס מבסיס הנתונים בזמני שיא — היישום כבר לא פותח מפולת של חיבורים חדשים בכל פרץ, ותור השאילתות הפסיק להיתקל בתקרת החיבורים.
במה שונה איזון חיבורים מרפליקציה
רפליקציה ואיזון פותרים משימות שונות, ובלבול ביניהם עולה ביוקר. הרפליקציה אחראית לכך שעותק של הנתונים יהיה קיים בצומת אחר: הצומת הראשי מעביר שינויים בזרם, הגיבוי מיישם אותם וזמין לקריאה בלבד. האיזון אחראי לנתיב השאילתה — לאיזה צומת היא תעבור ומה יקרה לה ברגע הכשל.
אם תגדירו רפליקציה זורמת, לא תפזרו את עומס הקריאה. הרפליקה מקבלת את אותם נתונים, אך היישום פונה לצומת הראשי כל עוד אין מנתב בינו לבין בסיסי הנתונים. PgPool-II פועל כאן: מפרק את השאילתה, שולח שינויים לצומת הראשי, מפזר את הקריאה בין הרפליקות ומחזיק מאגר חיבורים.
את הארכיטקטורה בוחרים לפי פרופיל העומס. אם הכתיבה דומיננטית, הרפליקות לא יפנו עומס מהצומת הראשי — הן רק חוזרות על השינויים. אם הקריאה דומיננטית, פיזור שאילתות הקריאה מסיר מהצומת הראשי חלק ניכר מהפניות, אך היישום צריך להשלים עם הפיגור של הרפליקה.
מכאן הסיכון המרכזי: כל עוד הצמתים מתפצלים, הרפליקה מחזירה נתונים מיושנים — המשתמש לא רואה רשומה שנשמרה זה עתה. הטעות ההפוכה גרועה יותר: שינוי עובר לצומת שהמנתב מחשיב בטעות לראשי.
ואז כבר הצמתים עצמם מתפצלים, וזה לא נרפא בהפעלה מחדש. לכן לצד האיזון הולכים בדיקות מצב הצמתים, הסבה אוטומטית לגיבוי והגנה מפני פיצול האשכול. מה לעשות בעת פיגור — להמתין, להוציא את הרפליקה מהפיזור או להעביר את הקריאה לצומת הראשי — מחליטים מראש.
ספקות טכניים לפני היישום: ניתוח
לפני יישום PgPool-II עולים בצוות אותן ספקות שוב ושוב: האם יהיה צורך לשנות את היישום, האם נדרשת השבתה, האם ההסבה האוטומטית תעבוד, ומה לעשות כשהנתונים מתפצלים.
האם יהיה צורך לכתוב את היישום מחדש?
לא. PgPool-II מתייצב בין היישום לאשכול ומדבר באותו פרוטוקול כמו שרת בסיס נתונים רגיל. משתנה רק מחרוזת החיבור — הדרייברים וספריות הגישה לנתונים ממשיכים לעבוד. באופן נקודתי בודקים שאילתות שתלויות בצומת אחד: רצפים (sequences) וקורסורים בצד השרת.
האם יישום על אשכול פעיל מחייב השבתה?
אין צורך בהשבתה. PgPool-II עולה לצד האשכול הקיים; תחילה מעבירים אליו את הקריאה ובוחנים את ההתנהגות תחת עומס, ואת הכתיבה — אחרונה. לכך נדרשת השהיה של שניות כדי שטרנזקציות פתוחות ייסגרו. החזרה לאחור — החזרת היישומים למחרוזת החיבור הקודמת.
כיצד בודקים את ההסבה האוטומטית?
בסביבת ניסוי הקרובה לזו של הייצור: עוצרים את הצומת הראשי ומתעדים את הזמן עד להעברת הרפליקה לראשי, את מספר הטרנזקציות שאבדו, ואת התנהגות היישום בעת ניתוק החיבור. לאחר מכן חוזרים על כך בחזרה גנרלית על מעגל הייצור — עם דוח ולוגים.
מה יקרה בעת פיצול נתונים?
PgPool-II עוקב אחר הפיגור של הרפליקות: בחריגה מהסף הצומת מוצא מחלוקת הקריאה — היישום לא מקבל נתונים מיושנים. צומת שנפל אחרי תקלה נבנה מחדש מעותק של הראשי. השהיית הרפליקציה, הזמינות והחלפת התפקיד מוצגים בלוח הניטור: ההתראה מגיעה לפני שהמשתמשים מבחינים בבעיה.
נדון במשימה ונחזור עם תוכנית עבודה
כדי שההערכה תישען על עובדות ולא על הנחות, כדי להתחיל מספיק תיאור של הארכיטקטורה הנוכחית ושל אופי העומס. נבחן היכן נמצאת כעת נקודת הכשל, כיצד מתחלקות הקריאה והכתיבה בין הצמתים, והאם נקודת כניסה אחודה ליישומים מוכנה.
מהלקוח נדרש מעט:
- תרשים המעגל: מספר צומתי PostgreSQL, קיום רפליקות, מצב הרפליקציה, ומי מנהל כיום את החלפת תפקיד הצומת הראשי.
- פרופיל העומס: שיעור הקריאה והכתיבה, תקופות שיא, דרישות לזמן התגובה לשאילתה.
- התנהגות היישומים: כיצד הם עוברים ניתוק חיבור, האם הם משתמשים בכתובת חיבור אחודה, והאם הם מוכנים לחזור על שאילתה כראוי לאחר ההסבה.
- מצבת החיבורים: כמה לקוחות מתחברים בו-זמנית והאם יש מאגר חיבורים בצד היישום.
- דרישות לכשל: זמן אי-זמינות מותר לכתיבה ולקריאה, והאם נדרשת החזרה אוטומטית של התפקיד לצומת הקודם.
- נהלים: חלון תחזוקה, הרשאות גישה לשרתים ולמערכות הניטור.
בעקבות הדיון נשלח תוכנית יישום: הרכב העבודות וסדרן, שלביות (הכנת הצמתים, הפעלת פיזור הקריאה, בדיקת החלפת התפקיד, בדיקת עומס), קריטריוני קבלה וסדר המסירה עם ליווי. תארו את המשימה — ונחזור עם הערכה ותוכנית.







