מדוע האינדקסר על go-ethereum מפגר אחרי ראש הרשת
הצומת מסונכרן עם הרשת, אך שכבת הנתונים של האפליקציה חיה בפיגור. אינדקסר הבלוקצ'יין קורא בלוקים, מפרק אותם לטבלאות ומעביר אותם לאפליקציה — ובדיוק בממשק הזה נוצר פיגור אחרי ראש הרשת: הממשק מציג יתרה שכבר לא קיימת, או לא רואה אירוע שאושר לפני מספר דקות.
הסיבות הן בדרך כלל הנדסיות, ולא "הרשת איטית". כתיבה מרוכזת למסד נתונים עם חלון רחב, עיבוד סדרתי בתהליך יחיד, מנוי לבלוקים חדשים ללא חיבור מחדש — לאחר ניתוק הטווח הולך לאיבוד, והאינדקסר על go-ethereum ממשיך מהמספר האחרון שנרשם, ומשאיר פער של בלוקים. ארגון מחדש (reorg) ברגע זה משכתב את הענף הקנוני, והאפליקציה כבר סיפקה נתונים לפי הענף הקודם.
המחיר של עיכוב כזה הוא אי-התאמה במצב. חישוב של פרוטוקול DeFi נשען על יתרה מיושנת, חלון הראווה של NFT מאבד טוקן שהונפק או החלפת בעלים, ופנייה לתמיכה משוחזרת רק בצד המשתמש: במסד הנתונים וב-API הכל "נכון", רק מהעבר.
הפיגור לא נעלם מעצמו: יש להדביק את הטווח שהוחמץ, ואת ההיסטוריה המשוכתבת — לכתוב מחדש בצורה נכונה, בלי לשכפל אירועים. להלן נבחן כיצד זה נסגר: מאישורים וכתיבה אידמפוטנטית ועד לסמן נפרד ומדד פיגור בבלוקים.
מה נותנת שכבת נתונים אמינה לשירותי DeFi ו-NFT
דרך שכבת הנתונים עובר כל מה שהמשתמש רואה: יתרות, היסטוריית פעולות, מצב פוזיציות בבריכות, בעלי טוקנים. אם לאסוף זאת ישירות מהצומת בכל בקשה, השהיית העדכון גדלה יחד עם מספר הלקוחות, וחוסר סנכרון ברגע חתימת העסקה מספק למשתמש מספרים מיושנים.
אנחנו בונים שכבה כזו על go-ethereum — ההתנהגות בזמן ארגון מחדש ועיבוד חוזר של בלוקים צפויה, מכיוון שהלקוח כבר פותר משימות אלו בעצמו.
עדכניות היתרות והאירועים
האינדקסר מקדם את מצביע המצב רק לאחר אישור הבלוק בעומק ההטמעה שהוגדר. זה מסיר סוג שלם של כשלים "הצגנו יתרה שכבר לא קיימת": לפני אישור, הנתונים נמצאים בשכבה ביניים ולא עוברים לממשק.
בזמן ארגון מחדש של השרשרת, החישוב מחדש מתבצע לפי יומן האירועים — השירות חוזר למצב עקבי תוך דקות, ולא קורא את ההיסטוריה מחדש.
עדכוני זרימה מסופקים דרך WebSocket: המנוי מקבל דלתא לפי הכתובות שלו במקום לתשאל את הצומת, ולכן השהיית העדכון נכנסת למרווח של בלוק אחד.
עמידות הקריאה בעומס שיא
הקריאה מופרדת מהכתיבה: האינדקסר כותב בקבוצות לאחסון, ה-API והמנויים קוראים מרפליקות וממטמון חם. שיא הפעילות מגיע עם הגידול במספר הכתובות, ולא עם המהירות של צומת בודד, — עומס הקריאה מתחלק אופקית, וזמן התגובה נשאר יציב כאשר פרץ מוסיף מנויים.
כשלים מדרדרים חלקית: כאשר רפליקה אינה זמינה, בקשות עוברות לנותרות, והאינדקסר ממשיך לכתוב. שכבת הנתונים מסירה מהצוות שני סוגי בעיות בבת אחת — יתרות לא מהימנות וחוסר זמינות של קריאה ברגע הכי לא נוח.
אפשרויות ארכיטקטורה לאינדקסר על go-ethereum
תכנית האינדקסר קובעת את התנהגות השירות בעת כשל במקור: האם ה-API ימשיך לספק יתרות ואירועים או ייכנס לשגיאה. להלן ארבע תצורות שאנו מיישמים ברשתות התואמות ל-go-ethereum, והמגבלות האמיתיות שלהן.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| צומת מלא משלך עם אינדקסר | שיטות מעקב פרטיות, גישה למאגר עסקאות, השהיה צפויה | דיסק וסנכרון ראשוני גדלים יחד עם הרשת; נדרשת השגחה על עדכוני הלקוח |
| ספק חיצוני לגישה לרשת | התחלה מהירה, בקשות נדירות, מספר רשתות בבת אחת | מגבלות קצב ועומק היסטוריה, אין שיטות פרטיות, תלות בזמינות של אחרים |
| היברידי: צומת משלך ראשי, חיצוני כגיבוי | מצב שבו הפסקה באינדקס אסורה | תחזוקה מורכבת יותר: שני מקורות, בקרת פיגור, החלפה |
| מנוי זרימה דרך WebSocket | התראות מקוונות ושירותים קלים ללא היסטוריה | בלוק שהוחמץ לא ניתן לשחזר, עם אתחול המצב הולך לאיבוד |
מתי צומת משלך משתלם יותר מצומת חיצוני
צומת משלך ניקח כאשר ההיסטוריה נטענת בקבוצות, והספק החיצוני מגביל את עומק הבקשות ואת תדירות הפניות. שיטות מעקב פרטיות וקריאת מאגר עסקאות מבחוץ לרוב אינן זמינות, באופן מקומי אלו קריאות רגילות לפורט שלך. השהיית התגובה אינה תלויה בתור של אחרים, ואת גרסת הלקוח מעדכנים לפי לוח הזמנים שלנו.
מצב היברידי וגיבוי מקורות
היברידי בונים כך: צומת — מקור ראשי, ספק חיצוני — גיבוי. האינדקסר כותב למסד הנתונים שלו ומשחזר טווחי בלוקים באופן אידמפוטנטי, ולכן ההחלפה לא קורעת את הנתונים.
תהליך שמירה משווה את הבלוק האחרון שעובד עם הרשת, ובמקרה של פיגור מעל הסף מעביר את התעבורה לגיבוי, ולאחר הדבקה מחזיר אותה בחזרה.
שלבי יישום: מביקורת צמתים ועד למסירה
ביקורת ותכנון מתבצעים לפני שורת הקוד הראשונה: לתפוס טעות בתכנית זרימות הנתונים כאן זול יותר מאשר לעשות מחדש לאחר עומס. כל שלב מסתיים בארטיפקט שניתן לבדוק לפני המעבר לשלב הבא. להלן כיצד העבודה בנויה.
- ביקורת צמתים וזרימות נתונים. אנו מתעדים את המצב הנוכחי: אילו לקוחות משמשים, היכן אירועים הולכים לאיבוד, כיצד בנויים המנויים, באיזו השהיה נתונים מגיעים לממשקים. מזהים צווארי בקבוק ואי-התאמות בין הרשת למסד הנתונים.
- תכנון סכמת האינדקס והאחסון. קובעים אילו אירועים אנו קוראים, כיצד אנו מקשרים אותם למצב, אילו אינדקסים נדרשים לבקשות טיפוסיות של ארנק, בריכה ואוסף. הסכמה מאושרת לפני המימוש.
- טיפול בנסיגות שרשרת. מגדירים עומק אישור, סדר שחזור בלוקים וניקוי רשומות שנפגעו — לאחר ארגון מחדש לא נשארות במסד הנתונים יתרות ובעלים לא קיימים.
- פריסת ממשקי קריאה. מקימים ממשק בקשות ומנויי זרימה, מגבילים את תדירות הפניות, מפעילים מטמון על בחירות חמות.
- בדיקת עומס. מריצים פרופיל של פניות אמיתיות: תדירות שיא של בקשות, אינדוקס מחדש המוני, פיגור האינדקסר, התנהגות כאשר הצומת אינו זמין.
- מסירה לתפעול. מוסרים תצורות, סכמות, מדיניות אתחול ושחזור, הוראות למשמרת תורנית.
נקודות בקרה בכל שלב
לשלב יש קריטריון מדיד: השהיית אינדוקס, שיעור בלוקים ששוחזרו כראוי לאחר נסיגה, זמן תגובה לבקשה חמה, שחזור ללא תיקונים ידניים. כל עוד הקריטריון לא מתקיים, לא ממשיכים הלאה — אי-התאמה בנתונים מתגלה בהגדרה, ולא בסביבת העבודה.
מה מוסרים לידיים: סכמות, מדיניות, תקנות
ערכת האספקה אינה ארכיון קוד מקור, אלא סט ארטיפקטים שלפיהם הצוות שלך יוכל לפרוס, לסגת ולתחזק שירותים בלעדינו. להלן מה בדיוק עובר לידיים ואיזו משימה סוגר כל מסמך.
- תצורות שירותים — חיבור לצומת (במעגל הבסיסי — go-ethereum), מגבלות בקשות בו-זמניות, גודל אצווה בקריאת בלוקים, זמני המתנה ומדיניות ניסיונות חוזרים. עבור כל ערך מצוינת ההתנהגות בעת גידול בעומס.
- סכמות פריסה וטופולוגיה — אילו רכיבים אינם שומרים מצב, היכן נמצאים מסד הנתונים והתור, כיצד התעבורה עוברת מהמאזן לצומת ולמנויי הסוקטים.
- מדיניות גישה ותפקידים — חשבונות נפרדים לשירותים, לתורן ולאנליטיקה, הרשאות מינימליות נדרשות, נוהל החלפת מפתחות.
- תקנון שחזור — זמן ונקודת שחזור יעד, עלייה מצילום, מעבר חוזר על בלוקים לאחר אי-התאמה והשוואה מול הרשת.
- תיאור פורמטי נתונים — סכמות טבלאות ואינדקסים, פורמט הודעות בסוקטים, כללי אידמפוטנטיות וטיפול בארגון מחדש של השרשרת.
- הוראות למשמרת תורנית — אילו אותות נחשבים טיפוסיים, עץ אבחון, מה בטוח להפעיל מחדש על ידי התורן ומה דורש הזעקת מהנדס.
תיעוד עבור צוות ההנדסה של הלקוח
בלוק נפרד — מה שנדרש לפיתוח, ולא לתפעול: נקודות הרחבה בקוד, רשומות על החלטות מפתח והסיבות לבחירה, רשימת תיוג לקבלה, נוהל חיבור חוזים ומדדים חדשים. שם גם — גבול האחריות: מה נשאר אצלנו ומה עובר לצוות שלך.
מקרה בוחן: צמצום אי-התאמת היתרות לאפס
אלינו הגיע פרוטוקול DeFi עם בריכות נזילות וחלון ראווה של NFT: הבקאנד ב-Go קרא את השרשרת דרך go-ethereum, אגר מצב במסד נתונים יחסי והעביר יתרות ב-REST API וב-WebSocket. המשתמש ראה בממשק סכום אחד, החוזה אישר אחר — התמיכה טבעה בפניות על יתרות "תקועות".
לפני השינוי, האינדקסר עיבד בלוקים באופן סדרתי: פיגור אחרי ראש השרשרת 40–90 שניות, שיעור אי-התאמות בהשוואה עד 0.8% מהכתובות, שחזור לאחר נפילה — יותר מ-40 דקות, מכיוון שהתהליך התחיל מאפס.
בשיא — פרץ פעולות פי חמישה — התור של בלוקים גדל, מנויים לאירועים ניתקו, חלק מההעברות לא באו לידי ביטוי כלל.
מה בדיוק שינו בתכנית האינדוקס
צוואר הבקבוק התברר לא כבקשות לצומת, אלא ככתיבת המצב והיעדר עמידות בפני ארגון מחדש. בלוקים החלו להיאסף בחבילות ולעבור עיבוד מקבילי, כתיבת הטווח מתבצעת בעסקה אחת; לוגים נכתבים באופן אידמפוטנטי לפי מפתח "בלוק + אינדקס לוג", ולכן מעבר חוזר לא יוצר זיכוי כפול.
ארגונים מחדש מטופלים במעגל נפרד עם נסיגה לפי נקודות בקרה במקום איסוף מלא מחדש, WebSocket מספק רק את דלתא היתרה, והשוואה יומית עם קריאה לחוזה מאירה אי-התאמות לפני המשתמש.
לאחר היישום, הפיגור נשמר בטווח של 1–2 שניות, ב-12 אלף בדיקות כתובות אין אי-התאמות, שחזור לאחר נפילה אורך 3–4 דקות — התהליך ממשיך מנקודת הבקרה האחרונה. שיא פעילות פי חמישה לא מגדיל את התור: החבילות מספיקות להיכתב, המנויים לא נקרעים.
במה שונה צומת ארכיוני מצומת מלא?
ההבדל בין מצבי הצומת הוא באיזה חלק ממצב הרשת הוא שומר ובאיזה עומק היסטוריה הוא מוכן להגיב. צומת מלא מחזיק מצב עדכני ובלוקים אחרונים: בקשות טריות מטופלות במהירות, אך פנייה לבלוק שרירותי בעבר תחזיר שגיאה.
צומת ארכיוני שומר מצבי ביניים מתחילת השרשרת — עומק ההיסטוריה מקסימלי, אך נפח האחסון וזמן הסנכרון הראשוני גדלים.
לקוח קל אינו שומר מצב כלל: הוא מקבל כותרות בלוקים ומאמת נתונים לפי הוכחות. לארנק זה מספיק, אבל לבקאנד שבונה אינדקסים ומחשב מחדש בחירות היסטוריות — לא.
המצב נקבע בעת הפעלת הלקוח: ב-go-ethereum אלו הם סטים שונים של דגלי סנכרון מצב, ומעבר ביניהם פירושו טעינה מחדש של נתונים, ולא שינוי הגדרה תוך כדי תנועה. לכן בחירת מצב הצומת נעשית לפני הפריסה — לפי אילו בקשות השירות מטפל.
| מצב | עומק היסטוריה | מהירות תגובה | אחסון | תרחישים |
|---|---|---|---|---|
| צומת מלא | מצב עדכני ובלוקים אחרונים | גבוהה בנתונים טריים | מתון | עיבוד אירועים חדשים, מנויים, יתרות נוכחיות |
| צומת ארכיוני | כל השרשרת מהבלוק הראשון | גבוהה בכל בלוק | כפול ומעלה | ביקורת, בחירות היסטוריות, חישוב מחדש של אינדקס מאפס |
| לקוח קל | כותרות בלבד | תלוי בצומת חיצוני | מינימלי | ארנקים, אימות קל של עסקאות |
ספקות טכניים לפני תחילת הפרויקט
לפני חישוב לוחות זמנים, מהנדסים בודקים ארבעה דברים: היכן נמצא הצומת, מה קורה לשירות בעת עדכון, כיצד המערכת מתנהגת בעת גידול בעומס ומי אחראי לאי-התאמה בנתונים. להלן תשובות קצרות; תחום האחריות וקריטריוני הקבלה נרשמים בכתב לפני ההתחלה.
יש לנו כבר צומת פרוס — האם צריך שני?
לא, אנו מתחברים לקיים במצב גישה ארכיונית. אם הוא אינו שומר את כל היסטוריית המצבים, האינדקסר על go-ethereum ישלים את הבלוקים החסרים בעצמו, ללא סנכרון מחדש מאפס.
האם עדכון יעצור את השירות?
לא. מעגל חדש עולה לצד, מדביק את גובה הבלוק הנוכחי, ורק אז מוחלפת התעבורה. הישן נשאר פעיל עד להשוואות הראשונות — נסיגה אורכת דקות.
מה יקרה בעת גידול חד בפעילות?
קריאת בלוקים מתבצעת בקבוצות, כתיבה — בעסקה אחת, ולכן זמן העיבוד גדל באופן ליניארי. API ו-WebSocket מופרדים לתהליכים נפרדים: פרץ מנויים אינו מאט את כתיבת האירועים.
כיצד נבדקת נכונות הנתונים?
כל בלוק נבדק לפי מספר וגיבוב (hash), מצב הכתובות מחושב מחדש מעת לעת מנקודות בקרה. אי-התאמה עוצרת את קידום האינדוקס ומגיעה לדוח, ולא נשלחת בשקט לתשובות ה-API.
נדון במשימה ונחזור עם הערכה ותכנית
לצורך התחלת דיון אין צורך במסמך מפורט — די במה שכבר יש לצוות שלך. שלח תרחיש שימוש: אילו פעולות נקראות ונכתבות, אילו נתונים נדרשים בזמן אמת, ואילו ניתן לאסוף בקבוצות.
אם יש סכמת נתונים, מודלים של חוזים וקוד צומת נוכחי ב-go-ethereum — הוסף אותם: לפיהם ניתן לראות היכן צוואר הבקבוק ומה יצטרכו לכתוב מחדש.
את המשימה מפרקים לשני שלבים: שיחת ועידה על ארכיטקטורה, ואחר כך ניתוח סכמת הנתונים ותרחישי כשל — מה עושים בעת ארגון מחדש של השרשרת, כיצד משחזרים את האינדקס לאחר תקלה, היכן עובר הגבול בין הצומת לשכבת השירות.
לסיכום, אנו מציעים הרצת פיילוט ברשת בדיקה: היא מראה את מהירות הסנכרון האמיתית ומסירה את הסיכונים העיקריים לפני תחילת העבודה העיקרית.
בתגובה תקבלו:
- הרכב העבודה לפי שלבים וגבולות אחריות;
- סכמת נתונים: טבלאות, אינדקסים, כללי אינדוקס מחדש בעת ארגון מחדש;
- חוזי API ופורמט הודעות WebSocket עם דוגמאות;
- תכנית פיילוט: היקף, משך, קריטריוני הצלחה;
- תרחישי כשל ונוהל שחזור האינדקס;
- הערכת לוחות זמנים לפי שלבים ודרישות לסביבה;
- קריטריוני קבלה ונוהל מסירת תיעוד.
תאר את המשימה בצורה חופשית — נחזור עם הערכה ותכנית עבודה.







