דילוג לתוכן הראשי
ניסיון מקצועי

שינוי בטוח במנוע הרצת מס בן 15 שנה

מודרניזציה הדרגתית של מערכת Legacy עם blast radius מבוקר, ולא כתיבה מחדש

מקור
Intuit, Senior Backend Engineer, Data Exchange Platform / IDX
Tech Stack
Java · Kotlin · Kafka · Pulsar · AWS · Kubernetes
פיתוח Backend, מערכות מבוזרות, ארכיטקטורת Event-Driven, אמינות,

אמל״ק

הבעיה
pipeline סקריפטים ה-Legacy למס, בן 15 שנה, היה צריך לעבור למנוע מודרני, ו-cutover של הכול בבת אחת סיכן זרימות נתונים ב-Production.
התרומה שלי
כחלק מהליבה של הצוות, המרתי ידנית את סקריפטי ה-Legacy למס ובניתי שינויים במנוע סביב המיגרציה: חילוץ מ-PDF, פרסום ל-Kafka, תיקוני קריאות יוצאות לספקים ו-flow אחסון לבדיקות shadow.
תוצאה וראיות
השוואת shadow ספק אחרי ספק מול מסלול ה-Legacy הגבילה את החשיפה לספק מאומת אחד בכל פעם. לא נמדדו נתוני ביצועים, ואין טענה לגבי מצבה של תוכנית המיגרציה הרחבה.
להעמקה בפרטים הטכניים

הבעיה

פלטפורמת הנתונים של Intuit מריצה מנוע הרצה ותיק ומבוסס. הוא מעבד נתונים מעשרות אלפי ספקים מבוססי API וסקרייפינג, עבור מוצרים כמו TurboTax, QuickBooks ו-Credit Karma. חלק מהפלטפורמה עדיין הסתמך על pipeline סקריפטים ה-Legacy, בן 15 שנה. בינתיים הצוות בנה סביבו מנוע מודרני שמבוסס על DSL פנימי.

החלפת pipeline ה-Legacy לכל הספקים בבת אחת הייתה מסכנת יחד קבוצה גדולה ובלתי צפויה של זרימות נתונים ב-Production.

הקשר

זו לא הייתה כתיבה מחדש מאפס. ה-pipeline ה-Legacy היה צריך להמשיך לשרת תעבורה חיה של ספקים לאורך כל המיגרציה. פגיעה בלקוחות לא הייתה מקובלת. הייתי חלק מהליבה של הצוות שהוביל את המיגרציה. בפלטפורמה כבר היו מוסכמות עבודה, צרכנים ב-downstream וחוזים של ספקים ב-Production.

אילוצים

  • ספקים הסתמכו על ההתנהגות הקיימת של pipeline ה-Legacy. אי אפשר היה להפסיק אף אחד מהם.
  • המנוע החדש היה צריך להוכיח התנהגות שקולה לפני שהוא לוקח תעבורה אמיתית של ספק כלשהו.
  • בלי פגיעה בלקוחות במהלך ה-cutover. מוצרי downstream תלויים במערכת הזו ישירות.
  • בלי cutover בו-זמני של כל הספקים. הבדל התנהגותי אחד שלא זוהה היה יכול להתפשט לכל בסיס הספקים.

התפקיד שלי

קידמתי את המיגרציה של סקריפטי ה-Legacy למס אל המנוע המודרני. הייתי חלק מהליבה של הצוות שאחראי על כך. המרתי את הסקריפטים ידנית. זה היה נפרד מהמיגרציה בסיוע AI של ספקים, שיש לה קייס סטאדי משלה.

גישת האימות ברמת ספק והתוכנית ל-rollout היו החלטות של הצוות. לא הייתי אחראי עליהן לבדי.

העבודה המעשית שלי היא בשינויים במנוע סביב המיגרציה:

  • מודול לחילוץ מ-PDF.
  • הרחבה שמאפשרת לסקריפטים לפרסם תוצאות ל-Kafka topics חיצוניים במהלך ההרצה.
  • ה-flow של קריאות ה-API החיצוניות של המנוע לספקים, שהייתי אחראי עליו. תיקנתי בעיות שהשפיעו על קריאות יוצאות לספקים מסוימים. המנוע כבר תמך בקריאות חיצוניות, ולכן זו הייתה עבודה בתוך יכולת קיימת.
  • flow ששומר פלט גולמי של ספקים באחסון S3 מוצפן. הוא קיים רק לבדיקות shadow ולאימות מיגרציה.

ההתנהגות של Retry ושל הצרכנים במנוע נובעת ממודל at-least-once היברידי קיים של Kafka/Pulsar. עבדתי בתוכו. לא הייתי אחראי עליו.

ארכיטקטורה וגישה

לא העברנו את כל הספקים בבת אחת. בחרנו ספק אחד. הרצנו את מסלול ה-Legacy ואת המסלול החדש שלו ב-shadow והשווינו את ההתנהגות. כל שאר הספקים נשארו על ה-pipeline הקיים. שני המסלולים היו צריכים להתאים זה לזה רק עבור הספק שאומת.

אחרי שהשוואת ה-shadow עברה בהצלחה, כתבנו תוכנית rollout. ה-cutover ל-Production חיכה עד שגם האימות וגם התוכנית היו במקום.

החלטות מרכזיות

  • אימות shadow ברמת ספק בודד במקום cutover גלובלי. אימות ההתנהגות של ספק אחד ב-shadow לפני שנוגעים ב-Production הגביל את ה-blast radius של כל פער לאותו ספק, ולא חשף את כל הספקים בו-זמנית למסלול שלא נבדק.
  • תוכנית rollout לפני פריסה ל-Production ולא אחריה. ה-cutover של ספק חיכה עד שהתוכנית נכתבה ושהשוואת ה-shadow אימתה את ההתנהגות של אותו ספק.
  • להשאיר ספקים אחרים על ההתנהגות הקיימת בזמן האימות. ספקים שעוד לא אומתו המשיכו לרוץ ללא שינוי על pipeline ה-Legacy, ולכן החשיפה לסיכון התרחבה בהדרגה, ספק מאומת אחד בכל פעם, ולא כולה בבת אחת.

שיקולים ופשרות

מעבר ספק אחרי ספק איטי יותר מ-cutover יחיד. זה גם אומר לשמור את מסלול ה-Legacy ואת המסלול המודרני זה לצד זה זמן ארוך יותר. שני מסלולים פעילים מוסיפים תקורה הנדסית ממשית.

המחיר קנה ביטחון. כל ספק הוכח כשקול לפני שהוא תלוי במסלול החדש. תוצאת shadow גרועה נשארה אצל ספק אחד, ולא צצה אחר כך בכל המערכת. התקורה משתלמת כשה-cutover המלא עלול לאיים ישירות על מוצרי downstream.

תוצאות ואימות

הקייס סטאדי הזה מתאר את השיטה, ולא את מצבה של תוכנית המיגרציה הרחבה. כל ספק הושווה ב-shadow מול מסלול ה-Legacy, ותוכנית rollout הוכנה, לפני כל cutover ל-Production. לא הייתה פגיעה בלקוחות ב-workstream הזה.

התכנון הגביל את החשיפה לספק מאומת אחד בכל פעם. הוא נבנה כך שבסיס הספקים כולו לא ייחשף למסלול שלא אומת.

לא נמדד שיפור ב-latency, בתפוקה או באחוזים עבור המיגרציה הזו, ואין טענה לגביו.

מה למדתי

מערכות בשלות מתגמלות שינוי הדרגתי יותר מכתיבה מחדש אגרסיבית. זה נכון במיוחד כשהמערכת כבר משרתת תעבורת Production אמיתית.

תאימות היא חלק מהפיצ'ר. היא לא משהו שמסמנים עליו וי לפני שהעבודה האמיתית מתחילה. לדעת מה תלוי במערכת חשוב יותר מהמהירות שבה אפשר לשנות אותה.

צמצום ה-blast radius היה חשוב יותר ממהירות ה-rollout. השוואת shadow ברמת ספק בודד נתנה את הבטיחות הזו בלי תשתית חדשה.