ניהול רענון דאטה ב-Tableau Cloud עם Airflow
3 דקות קריאה

אמ;לק
כאשר מריצים רענוני Extract ב-Tableau Cloud מתוך Airflow (במיוחד ב-MWAA), שימוש ב-Personal Access Tokens (PAT) יוצר צוואר בקבוק של סשן יחיד (Linear Session). ניסיון לעבודה מקבילית גורם לביטול סשניים (Error 401002). הפתרון לטווח הקצר הוא שימוש ב-Airflow Pools לסריאליזציה של הקריאות ל-API, בעוד הפתרון לטווח ארוך הוא מעבר ל-JWT Connected Apps, בכפוך למגבלות גרסאות ה-Providers ב-MWAA
רקע: השאיפה למקביליות ב-BI Orchestration
בסביבת הפרודקשיין שלנו, המבוססת על AWS Managed Workflows for Apache Airflow (MWAA) בגרסה 2.10.3, המטרה הייתה פשוטה: לנהל עשרות זרימות BI עצמאיות במחזור של 4 שעות.
הארכיטקטורה נראתה מצוין: DAG מבוסס קונפיגורציה, שבו כל Flow כולל טרנספורמציה ב-dbt cloud ולאחריה רענון של ה-Datasource ב-Tableau. רצינו מקביליות מקסימלית כדי שזמן הריצה הכולל ייקבע לפי ה-Flow הארוך ביותר, ולא לפי סכום כל הריצות. אבל אז פגשנו את ה-API של Tableau.
איך זה עובד (או למה ה-PAT שובר אתכם)
הבעיה הראשונה נעוצה בניהול הסשנים של Tableau REST API. כשאנו משתמשים ב-PAT, ה-Site logic אוכף קשר לינארי קשיח:
טאסק ראשון מבצע
sign_in()ומקבל טוקן-1טאסק שני (רץ במקביל) מבצע
sign_in()עם אותו PAT ומקבל טוקן-2הזמן הזה Tableau Cloud מבטל מיד את טוקן-1
טאסק ראשון מנסה להשתמש בטוקן המבוטל ומקבל
(Unauthorized Access) 401002
זהו מנגנון אבטחה מתועד, אך הוא כופה סריאליזציה מלאה על כל מה שמנסה להתחבר תחת אותה זהות PAT.

ניתוח האפשרויות: ממבוי סתום לפתרון
ניסינו לחזור לשיטה הישנה של שם משתמש וסיסמא, אך נתקלנו ב-MFA Wall. מאז 2022, Tableau מחייבת MFA, מה שהופך אוטומציה מבוססת סיסמה לבלתי אפשרית ללא התערבות אנושית או מעקפים מורבים.
הפתרון ה״נכון״ הוא JWT Connected App, המאפשר Stateless Authentication ותומך בסשנים מרובים במקביל. עם זאת, ב-MWAA גילינו את ״שומר הסף של הסביבה״: גרסת ה-Tableau Provider נעולה על 4.5.0, בעוד שתמיכה ב-JWT נוספה רק ב-5.2.0. ניסיון לדרוס את הגרסה בrequirements.txt נכשל בגלל קובץ ה-Constraints הקשיח של AWS.
טבלת השוואת אסטרטגיות אימות:
שיטת אימות | מודל קונקירנסי | תואם MFA? | תמיכה ב-MWAA (Native) | סטטוס |
PAT | ליניארי / סשן יחיד | כן | נתמך (4.5.0) | בשימוש (עם Pool) |
User/Pass | רב-סשנים | לא | נתמך | חסום ע"י MFA |
Connected App (JWT) | רב-סשנים / Stateless | כן | מגרסה 5.2.0 בלבד | Roadmap |
הפתרון המעשי: Airflow Pools כשסתום לחץ
התובנה הייתה שלא צריך לשנות את הטופולוגיה של ה-DAG, אלא להשתמש במנגנון ניהול המשאבים של Airflow כדי לנהל את צוואר הבקבוק.
יצרנו Airflow Pool בשם tableau_refresh_pool עם Slot אחד בלבד. בעוד שמשימות ה-dbt רצות במקביל ומנצלות את כל ה-Workers, משימות הטאבלו ממתינות בתור. כך אנחנו מבטיחים שרק Worker אחד מחובר ל-Tableau בכל רגע נתון, מה שמונע את ה-Race Condition.
דוגמת קוד: DAG Factory מבוסס קונפיגורציה
כך אנחנו מחילים את המגבלה בצורה דינמית:
# Deploy TableauOperator with Pool
for luid in conf['tableau_datasource_luids']:
TableauOperator(
task_id=f"refresh_{luid[:8]}",
site_id="my_site",
resource="datasources",
method="refresh",
find=luid,
pool="tableau_refresh_pool" # הקסם שמונע 401002
) >> dbt_task
סיכום
Auth is Architecture: שיטת האימות היא לא רק עניין של אבטחה, היא מכתיבה את יכולת ה-Scaling של המערכת.
מגבלות נסתרות: בשירותים מנוהלים כמו MWAA, תמיד תבדקו את קובץ ה
constraints.txtלפני שאתם מתכננים פיצ׳רים שמסתמכים על גרסאות provider חדשות.Pools הם כלי אסטרטגי: השתמשו בהם כדי להפריד בין הטופולוגיה הלוגית של ה-DAG לבין מגבלות פיזיות של API חיצוניים.
