למה פארסינג של סיירי בלוקצ'יין הופך לצוואר בקבוק
כשאינדקס עסקאות נבנה מעל סיירי בלוקצ'יין ציבוריים כמו Etherscan, הכול נתקע בכללים של מישהו אחר. פארסינג של סיירי בלוקצ'יין נשען על מגבלות בקשות לשירותים חיצוניים: מכסות יומיות, חלונות תדירות פניות, וחובת דפדוף לפי קורסור.
בטווחים ארוכים זה יוצר היסטוריית בלוקים קטועה — הסריקה נעצרת באמצע, וחזרה מאותו קורסור מחזירה פרוסת נתונים אחרת.
הצרה השנייה היא נתוני עסקאות חסרים. שירות חיצוני יכול לא למסור העברות פנימיות, אירועי חוזים או סטטוס סופיות, וחלק מהכתובות מסומנות כקוד בר-הרצה רק לפי הרגע שבו הוא מופיע ברשת. בסופו של דבר אותו בלוק מתואר אחרת אצל שני מקורות: הסכומים מתאימים, אבל הרכב הפעולות — לא. זמן הצוות מתבזבז לא על אנליטיקה, אלא על התאמות ידניות וניתוח אי-התאמות.
מכאן נכנס צוואר הבקבוק של האינדוקס: בזמן שהנתונים נטענים בהדרגה, דוחות, התראות ויתרות ארנקים מציגים את המצב של אתמול. בלוק אחד שהוחמץ נמשך דרך כל שרשרת החישובים התלויים וצף אצל הלקוח — בייצוא, בהתאמה או בהחלטת סיכון.
עברנו את הדרך הזו: התחלנו בבניית מדגמים דרך ממשקים ציבוריים ונתקענו בדיוק באותן תקרות. נסביר איך זה נסגר ואיפה נגמר השירות החיצוני ומתחילה מערכת שאתם שולטים בה בעצמכם.
מה נותן צינור עיבוד מנוהל לניתוח נתוני בלוקצ'יין
דרך סיירים ציבוריים הנתונים מגיעים בצורה לא אחידה: קצב האיסוף נקבע לא על ידי צינור העיבוד שלנו, אלא על ידי מגבלת בקשות חיצונית. מספיק לעבור את הסף — וחלק מהבקשות חוזרות עם דחייה, ואם המטפל לא מנהל יומן טווחים, הבלוקים האלה נושרים מהמרשם. הטעות מתגלה לא מיד, אלא בהתאמת יתרות אחרי שבועות, כששחזור החמצה יקר יותר מאיסוף הנתונים מחדש.
נודה עצמאית מסירה את סוג הכשלים הזה. אנחנו קוראים בלוקים ישירות מיומן האירועים ומחזיקים מצביע לבלוק המעובד האחרון, ולכן מגבלות של ספק חיצוני מפסיקות לקבוע את הקצב. האיסוף מתבצע ברצף: התור מתמלא מהנודה, ולא מתשובות של שירות זר. Etherscan וסיירים דומים נשארים שימושיים לבדיקה חוזרת נקודתית של עסקאות.
שלמות המרשם נשענת על כתיבה אידמפוטנטית: מפתח הרשומה — האש העסקה ואינדקס האירוע, ולכן עיבוד חוזר של טווח לא יוצר כפילויות. יומן הריצות שומר את גבולות כל טווח ואת הסטטוס שלו, כך שאפשר להריץ מחדש כל קטע נקודתית, בלי להפעיל מחדש את כל צינור העיבוד.
האפקט מדיד בשלושה מדדים: זמן איסוף תקופה היסטורית, שיעור רשומות אבודות ומספר כשלים בגלל מגבלות. הראשון יורד פי כמה בזכות קריאה מקבילה, השני שואף לאפס — החמצה נראית ביומן, ולא בפער בין סיכומים. התאמת כתובות ויתרות מפסיקה להיות ביקורת חד-פעמית ומתבצעת לפי לוח זמנים.
דרכי איסוף נתונים: ממשק ציבורי, נודה עצמאית, ארכיון
בחירת דרך הגישה קובעת לא רק את מהירות הפיתוח, אלא גם אילו שאלות אפשר בכלל לשאול את הנתונים. ממשק תוכנה ציבורי של ספק סוגר תרחישים טיפוסיים תוך ימים ספורים, אבל יוצר תלות במגבלות ובהרכב המתודות של אחרים. נודה עצמאית נותנת שליטה בבקשות ובהיסטוריה, אך דורשת משאבים לסנכרון ולתחזוקה.
ההסתעפות המרכזית היא האם נדרש עומק היסטוריה. בלוקים עדכניים ויתרות נוכחיות מספק כמעט כל מקור, אבל מצב בגובה שרירותי בעבר זמין רק במקום שבו נשמר ארכיון בלוקים: נודה רגילה חותכת מצבים ישנים, וחלק מהבקשות פשוט לא מבוצעות. לכן מקורות משולבים לרוב: ממשק ציבורי — למשימות תפעוליות, ארכיון — לאנליטיקה ולהתאמה.
| שיטה | מתי מתאימה | מגבלות |
|---|---|---|
| ממשק תוכנה ציבורי של ספק | גרסאות ראשונות של מוצר, תרחישי ארנק, מעקב אחר עסקאות עדכניות | מגבלות בקשות, היסטוריה חלקית, הרכב מתודות ועומק משתנים לפי החלטת הספק |
| מינויים זורמים של ספק | ניטור אירועים בזמן אמת ותגובה אליהם | העבר אינו זמין, יש להשלים פער אחרי ניתוק חיבור במעבר נפרד על ההיסטוריה |
| נודה עצמאית | עצמאות ממגבלות של אחרים, כללי אינדוקס משלכם | סנכרון ראשוני ארוך, נפח אחסון גדל, תחזוקה מתמדת |
| ארכיון בלוקים על נודה עצמאית | אנליטיקה, ביקורת, שאילתות מצב בכל גובה | האחסון גדל מהר יותר באופן ניכר מנודה רגילה, דרישות חומרה גבוהות יותר |
| שכבת אגרגציה משלכם מעל הארכיון | שאילתות מורכבות, דוחות ומדדים לפי כללים משלכם | נדרשת תמיכה בכוחות הצוות, ואי-התאמות עם נתוני מקורות חיצוניים יש להתאים |
את מגבלות הספקים כדאי לבדוק לפני ההתחלה: אילו מתודות זמינות, מה עומק ההיסטוריה, איך השירות מתנהג תחת עומס שיא והאם הוא מתריע על שינויים. אנחנו מתעדים זאת בסכמת המקורות — כדי שהמעבר לנודה עצמאית יהיה צעד מתוכנן, ולא חירום.
שלבי יישום: מביקורת משימות ועד העברה לתמיכה
סדר העבודות זהה גם לרשת אחת וגם למערכת רב-רשתית: קודם מתעדים מה בדיוק צריך לקרוא מהשרשרת, אחר כך מתארים זרימות, ורק לאחר מכן פורסים תשתית. כך נמנעת המצב שבו הנודה כבר הוקמה ומסונכרנת, אבל הנתונים לא מתאימים לסייר.
- ביקורת מקורות נתונים. אילו רשתות, חוזים וסוגי אירועים נדרשים, מה מספק ה-API הציבורי, היכן יש מגבלות על תדירות בקשות ומהו עומק ההיסטוריה הזמין. בפלט — רשימת מקורות עם המגבלות שלהם.
- סכמת זרימות. מפרידים בין מה שקוראים ישירות מהנודה לבין מה מה-API, היכן נמצא אחסון ביניים ואיך מטופל ארגון מחדש של השרשרת. את הסכמה מאשרים לפני תחילת הפיתוח.
- פריסה והגדרה. מקימים נודה מלאה או ארכיונית, מגדירים אינדוקס, תורים וניסיונות חוזרים בעת תקלות. הכתיבה נעשית אידמפוטנטית, כדי שמעבר חוזר לא יכפיל אירועים.
- בדיקה באמצעות התאמה. משווים ייצוא למקור ייחוס — סייר או מקור בלתי תלוי שני, מתאימים סכומי בקרה לפי בלוקים ויתרות סופיות. כל אי-התאמה מנתחים לפני ההפעלה.
- עומס ועמידות לתקלות. מריצים על עומק היסטורי, בודקים התנהגות בזמן אי-זמינות של הנודה והתאוששות לאחר ניתוק, מתעדים זמן השלמה לאחר השבתה.
- העברה לתפעול. מוסרים נהלים, לוח ניטור עם התראות על פיגור, הנחיות לתורן והדרכת הצוות. בהמשך — ליווי אחריות: מכווננים מקרי קצה ונשארים בקשר.
סכמות, מדיניות גישה ונהלים: מה נשאר במערכת
מערכת הפארסינג חשובה לא בכך שהיא עובדת היום, אלא בכך שאפשר לשחזר ולתקן אותה בידיים זרות. לכן להעברה נכנסים לא רק שירותים, אלא גם ארטיפקטים: קונפיגורציות, סכמות וכללים שלפיהם המערכת חיה אחרי ההפעלה.
- מפת מקורות — אילו נתונים מאיפה מגיעים: ממשקים ציבוריים של סיירים, נודות עצמאיות, ספקי גיבוי, ומה מוחלף במה בעת כשל.
- סכמות זרימה — המסלול של אירוע מהבלוק ועד האחסון והוויטרינות: איפה נרמול, איפה דה-דופליקציה, איפה ניסיונות חוזרים, ואיפה הסדר יכול ללכת לאיבוד.
- קונפיגורציות נודה — רשתות, עומק אחסון, מגבלות חיבורים, מצב אינדוקס והסבר מה משתנה עם גידול בעומס.
- מדיניות גישה — תפקידי שירותים, מפתחות, כללי רשת, הרשאות קריאה וכתיבה, ובנפרד נוהל שלילת גישות.
- נוהל תגובה לתקלות — טבלת «סימפטום → בדיקה → פעולה»: פיגור באינדוקס, קרע בשרשרת, אי-זמינות ספק, אי-התאמת נתונים.
- מדדים וספים — אילו אותות נחשבים תקינים, אילו חירום, למי ולאן נשלחת התראה.
- הנחיות תפעול — איך לפרוס מערכת מאפס, איך לבצע אינדוקס מחדש לקטע היסטוריה, איך לחבר רשת חדשה.
עם הסט הזה צוות הלקוח מוסיף רשת או מחליף ספק לפי הנחיות, בלי לפרק את הארכיטקטורה מחדש.
מקרה בוחן: הסרנו השבתות והאצנו התאמת נתונים פי כמה
הלקוח — שירות אנליטיקה לרשת Ethereum — אסף היסטוריה דרך ממשקים ציבוריים של סיירים, כלומר פארסינג רגיל של סיירי בלוקצ'יין. בשיאי עומס הבקשות נתקעו במגבלות, בעת ארגון מחדש של השרשרת חלק מהבלוקים אבדו, ובבסיס הנתונים הופיעו קרעים וכפילויות.
שיעור הרשומות האבודות הגיע ל-6–7%, ואי-התאמות עם הרשת נמצאו רק ידנית — כ-30 התאמות בחודש, כל אחת על ייצואים.
הרכבנו צינור עיבוד עצמאי: נודה עצמאית כמקור, זרם בלוקים ואירועים, כתיבה לפי מפתח «גובה בלוק + כתובת אירוע» — לכן עיבוד חוזר של טווח לא יוצר כפילויות.
בעת ארגון מחדש של השרשרת הטווח נקרא מחדש אוטומטית, בקשות כושלות עוברות לניסיון חוזר עם השהיה גדלה, והפיגור מול ראש השרשרת נראה בגרף ומעלה התראה לפני שהנתונים מתחילים להיות לא עקביים.
הוספנו התאמה אוטומטית: סכומי בקרה לפי טווחים מושווים למקור בלתי תלוי, ואי-התאמות מסווגות לפי סוגים — החמצה, כפילות, שדה שגוי. התאמות ידניות ירדו ל-1–2 בחודש במקום 30, וכל אחת אורכת דקות: המהנדס מסתכל על דוח אי-התאמות ולא משווה ייצואים גולמיים.
מעבר היסטוריה מלא התקצר מ-14 שעות ל-40 דקות בזכות עיבוד מקבילי של טווחים וקריאה מקומית במקום בקשות חיצוניות. נעלם סוג שלם של כשלים: אובדן בגלל מגבלות של ממשקים ציבוריים ו«חורים» אחרי ארגון מחדש של הרשת. בזרם חי שיעור הרשומות האבודות נשאר אפס, והייצוא היומי מתאים לרשת בלי התערבות ידנית.
במה ממשק ציבורי שונה מנודה עצמאית
ממשק ציבורי הוא תשתית של אחרים: מישהו אחר מחזיק עותק של השרשרת ומספק לכם נתונים לפי בקשה. נודה עצמאית היא אותו עותק מצב, אבל אצלכם, ואתם מחליטים מה ובאיזה נפח לאינדקס. ההבדל מתבטא בשלושה מקומות: עומק ההיסטוריה הזמינה, התנהגות הזרימה תחת עומס, ואיפה הקשר נקרע בעת תקלה.
בעומק, שערים ציבוריים כמעט תמיד מספקים רק חלון עדכני של בלוקים ואירועים — בקשות עמוקות נדחות או נחתכות לפי טווח. נודה ארכיונית אצלכם שומרת היסטוריה מהבלוק הראשון, ולכן חישוב מחדש של מדדים לתקופות קודמות ושחזור אירועים שהוחמצו לא נתקעים במגבלה של אחרים. זה בדיוק מה שקובע אם אפשר להשלים אינדקס בדיעבד או שנתונים יצטרכו להיאסף רק קדימה.
תחת עומס, ממשק ציבורי מטיל מגבלות על תדירות פניות, עונה בהשהיה משתנה ובאיכות שונה אצל מפעילי שער שונים. נודה עצמאית מוגבלת בדיסק וברשת, ולא במגבלה של אחרים: מקביליות בקשות, גודל אצווה ועומק מטמון אתם קובעים בעצמכם ורואים במה אתם נתקעים.
שער ציבורי הוא נקודת כשל חיצונית: שינוי תנאים, אינדוקס מחדש בצד של אחרים או השפלה של נודה עוצרים את האיסוף בלי השתתפותכם. נודה עצמאית מעבירה את האחריות פנימה: נדרשים בקרת פיגור מול ראש השרשרת, טיפול בארגונים מחדש וכתיבה אידמפוטנטית, כדי שמעבר חוזר לא יכפיל אירועים.
הבחירה בדרך כלל אינה בינארית: ממשק ציבורי סוגר מחקר ומשימות חד-פעמיות, ונודה עצמאית — איסוף קבוע עם היסטוריה מלאה.
מה מבררים לפני ההתחלה: מגבלות, היסטוריה, כשלים
לפני שבונים סכמת ניתוח, מהנדסים מתעדים את גבולות הנתונים הזמינים: אילו שירותים חיצוניים מספקים היסטוריה, לפי איזו מגבלת בקשות, עד לאן היא נמשכת אחורה ועד כמה היא מלאה. בלי ספירת מצאי כזו, צינור העיבוד מתמלא עד להיתקלות הראשונה במגבלה או מגלה פער בעומק כבר בשלב האנליטיקה. להלן הספקות שצפים לרוב בשלב הזה.
שירות חיצוני משנה מגבלות או סוגר גישה — מה אז?
מגבלות של שירותים חיצוניים אינן קבועות: מורידים אותן, מציגים שכבות בתשלום, ולפעמים מכבים שיטות ישנות. לכן הגישה עטופה בשכבת מתאמים נפרדת — החלפת מקור או מגבלה לא נוגעת בלוגיקת העיבוד. בנוסף, אנחנו תמיד מגדירים מקור נתונים משלנו כמסלול גיבוי.
עומק ההיסטוריה הזמין לא יספיק למשימות שלנו?
ממשקים ציבוריים בדרך כלל מספקים לא את כל השרשרת, אלא חלון של כמה חודשים עד שנתיים. אם נדרשים מצבים מוקדמים יותר, מקימים נודה עצמאית וקוראים בלוקים ברצף או משלימים את הקטע החסר ממקורות ארכיוניים. ההחלטה מתקבלת לפי אופק קונקרטי, ולא «ליתר ביטחון».
איך לוודא שהנתונים מלאים וללא החמצות?
בדיקת שלמות נשענת על התאמה: רציפות מספרי בלוקים, התאמת סכומי בקרה במדגם, התכנסות אגרגטים עם מקור בלתי תלוי. אי-התאמות נרשמות בנפרד ולא נמסות בזרם הכללי — כך החמצה נראית מיד, ולא אחרי חודש בדוח.
אפשר להתחיל בקטן ולהתרחב?
כן, וזה הסדר הנכון. קודם חוזה אחד או סוג אירועים אחד, ניפוי באגים עליו, ואז הרחבה מדורגת של הכיסוי — רשתות חדשות, טוקנים, תקופות היסטוריות. כל שלב נוסף בלי לשכתב את הקודם, לכן נפח האחסון גדל באופן צפוי ונשאר בשליטה.
נדון במשימה: מה נדרש מכם להערכה ולתוכנית
כדי לחזור עם הערכה ותוכנית, אנחנו צריכים לא רעיון כללי, אלא נתוני פתח לגבי נתונים ותשתית. להלן צ'קליסט: אם חלק מהסעיפים עדיין לא מוגדרים, נתעד הנחות ונבהיר אותן בשלב התכנון, ולא באמצע העבודה.
- אילו רשתות וישויות נדרשות: עסקאות, העברות טוקנים, קריאות פנימיות, אירועי חוזים, יתרות — ובאיזה פורמט למסור אותן החוצה.
- מאיפה לוקחים נתונים: API ציבורי של סיירים, ספקים עם אינדוקס מוכן או נודה עצמאית עם ארכיון מלא.
- נפחים ותדירות עדכון: עומק היסטוריה, זרם בלוקים חדשים, פיגור מותר וחלון חישוב מחדש.
- סכמת אחסון ושאילתות: איפה מאחסנים, מי קורא, לפי אילו מפתחות בונים שאילתות, איזה נפח מחזיקים חם.
- גישות ותפקידים: מפתחות ל-API, פרטי גישה לנודות, הרשאות כתיבה לאחסון, מי מצדכם מאשר שינויים.
- כללי אמינות: איך מתאימים החמצות ואי-התאמות בארגונים מחדש של השרשרת, מה נחשב למקור ייחוס.
- מצב מסירה: פרוסה חד-פעמית, זרם קבוע או חישובים מחדש קבועים; האם נדרש שחזור חוזר ורולבק.
תארו את המשימה בצורה חופשית וצרפו את מה שכבר קיים — נדון באפשרויות הפתרון. לאחר מכן נחזור עם הערכה ותוכנית עבודה: שלבים, לוחות זמנים, הרכב הבדיקות ונקודות שבהן יידרש אישורכם.







