題幹與適用情境
一條訂單資料管線每天從不可變物件儲存讀取 2 TB 原始資料,產生按 business_date 分割的 orders_daily。團隊發現一個稅費轉換缺陷,確認過去 90 個分割區都受影響,因此需要在 5 天內 重算 180 TB。同時,每日增量管線不能停,P95 新鮮度仍須不超過 45 分鐘;延遲退款和訂單更正還 可能與回填寫入相同業務鍵。
請設計一套能重複執行、暫停後恢復、稽核和回復的回填方案。回答至少要涵蓋:如何固定輸入與 程式碼版本,如何切分和排程分割區,怎樣避免歷史工作搶占生產資源,如何處理回填與目前增量的 重疊,哪些驗證必須阻擋發布,以及失敗後怎樣恢復到上一個可信版本。
近期公開資料工程面試材料直接把歷史回填、等冪重跑和「不影響即時處理」列為管線可靠性問題; 公開情境題還要求候選人處理 TB 級輸入、分割區重處理、驗證和回復。官方管線文件則明確提供歷史 日期執行、重處理策略和獨立並行上限。這個題目的搜尋意圖很具體:候選人需要給出一份可執行的 生產方案,「用 Airflow 重跑過去 90 天」只涵蓋了排程入口。
面試官考察點
第一項是先定義可重現的資料版本。好的回答會固定回填範圍、邏輯日期、來源快照或來源版本、轉換 程式碼、相依維度表版本和目標結構。若同一分割區兩次讀到不同輸入,或程式碼依賴 now()、隨機數 和可變外部查詢,「重跑安全」就沒有可驗證的意義。
第二項是把編排成功與資料正確分開。排程器可以為歷史邏輯日期建立執行並限制並行,但不會自動 讓業務寫入具有等冪性,也不會處理目前增量與歷史回填的寫入衝突。候選人需要選擇按分割區替換、 穩定主鍵 MERGE 或版本化目標,並說清楚適用前提。
第三項是容量和隔離。180 TB 在 5 天內完成,原始資料的平均最低讀取速率為:
180 TB / (5 × 24 h) = 1.5 TB/h ≈ 417 MB/s這只是連續執行且沒有重試的下限,不包含掃描放大、shuffle、目標寫入、驗證和失敗重算。好的回答 會先做單一分割區基準測試,測出每個階段的吞吐與峰值資源,再設定單獨佇列或運算池、並行上限和 生產優先級,用目前管線的新鮮度自動收緊回填速率。
第四項是發布與恢復邊界。90 個工作成功不代表新版本可以被消費者讀取。發布前要證明分割區完整、 主鍵唯一、業務不變量成立、來源可對帳且差異符合本次缺陷;發布應是一次受控的版本切換。舊版本 保留到觀察期結束,發生問題時可以直接切回指標,避免再次重跑 180 TB。
回答前需要釐清的問題
- 原始輸入真的不可變嗎? 需要物件版本、快照 ID 或可重播日誌位置;若來源會原地改寫,先建立
可引用的輸入版本。
- 90 天的邊界按什麼時間定義?
business_date、事件時間、接收時間和時區必須統一;延遲退款
落在哪個分割區也要明確。
- 目標表的資料粒度和穩定鍵是什麼? 每列是訂單、訂單項目還是日彙總;是否有
order_id、
source_version 和確定的衝突順序。
- 轉換還依賴哪些可變資料? 匯率、稅率、SCD 維度表和刪除記錄需要按歷史時間點讀取,不能預設
用今天的值重算過去。
- 目前增量會觸及哪些分割區? 若增量只寫最近 7 天,較舊分割區可獨占;若能更正任意歷史訂單,
就需要版本順序或增量追平。
- 平台有哪些隔離和原子發布能力? 獨立倉儲、資源池、優先級佇列、分割區交易、資料表複製、
檢視切換或 catalog 指標會影響方案。
- 5 天是硬性期限還是期望值? 還要給目前 P95 新鮮度、來源系統讀取配額、成本上限和允許的
短暫切換視窗。
- 驗收由誰簽核? 技術斷言、財務對帳、下游抽樣和觀察期分別需要負責人與阻擋閾值。
30 秒回答框架
「我先凍結 90 個業務日、輸入快照和程式碼版本,按邏輯日期把分割區寫入隔離 staging 並記錄 清單。180 TB/5 天至少需要約 417 MB/s,先做基準測試;生產 P95 接近 45 分鐘就限速。回填 W0 後追平到 W1,90/90 分割區、對帳和業務檢查通過才切換;保留舊版本用於回復。」
分步深入解答
第一步:把回填定義成一個不可變執行規格
建立 backfill_id,記錄如下內容:
| 欄位 | 範例 | 作用 | |---|---|---| | 範圍 | [2026-04-01, 2026-06-29],90 個分割區 | 防止邊界在執行中漂移 | | 輸入 | rawsnapshot=s1042,水位 W0 | 讓重試讀取同一份事實 | | 邏輯 | codesha=abc123,taxrules=v17 | 固定轉換和相依版本 | | 輸出 | ordersdailybf20260718 | 與目前可信版本隔離 | | 資源 | 回填池、最大並行、讀寫配額 | 保護生產 SLO | | 門檻 | 唯一鍵、金額差、完整性、簽核人 | 把「完成」變成可判定狀態 |
business_date 要作為參數傳入每次分割區執行。轉換內禁止用目前牆鐘時間替代邏輯日期;依賴歷史 匯率或 SCD 維度表時,按事件時間點做 as-of join。輸入、程式碼或相依版本任何一項變更,都應建立 新的 backfill_id,不能把兩套結果混在一次執行裡。
先產生執行計畫,不寫生產目標:列出 90 個分割區、相依順序、估算輸入位元組、預計並行和目標 路徑。檢查空洞、重複日期、超出來源保留期的分割區及下游副作用。電子郵件、帳單、外部 API 等 非資料輸出必須關閉或改為稽核模式,避免歷史重播再次觸發真實業務動作。
第二步:用分割區清單提供暫停、恢復和稽核
每個 business_date 是一個有界工作單元,清單至少記錄:
backfill_id, business_date, input_snapshot, code_sha,
state, attempt, input_rows, output_rows, output_checksum,
staging_location, published_version, started_at, completed_at狀態可採用 PENDING → RUNNING → VALIDATED → PUBLISHED,失敗進入 FAILED。領取工作前用條件更新 或租約確保一個分割區只有一個活躍擁有者;租約逾時後可以重新領取。重試只重算失敗分割區,並 寫入同一分割區的隔離 staging 版本,不能向最終表盲目附加。
若目標按日期完全封閉,最簡單的等冪寫法是「建立完整分割區後以交易方式替換該分割區」。若目標 允許同一訂單跨日更正,使用穩定業務鍵和來源版本做 MERGE,並定義明確的勝出順序,例如先比較 sourceupdatedat,相同時間再比較單調 source_sequence。只有主鍵、版本和刪除語意都可靠時, MERGE 才能防止舊歷史記錄覆蓋新更正。
第三步:用基準資料推導並行
180 TB/5 天給出約 417 MB/s 的原始讀取下限。先選 1 個有代表性的分割區做 canary,記錄讀取、 解壓縮、shuffle、轉換、寫入和驗證各階段的位元組、時間、CPU、記憶體、倉儲佇列時間及暫存空間。 假設單一分割區有效吞吐為 r MB/s,理論並行下限約為 ceil(417/r);實際值還要受來源讀取配額、 shuffle 峰值、目標提交能力和成本預算限制。
回填使用獨立運算池或佇列,優先級低於每日增量;同時限制排程並行、來源端讀取、目標寫入和總成本, 只限制其中一項通常不夠。控制器持續觀察目前管線的 P95 新鮮度、倉儲排隊和來源限流:延遲接近 45 分鐘時停止領取新分割區或降低並行,恢復到安全區間後逐步增加。已經提交的分割區不強制終止, 避免留下半成品;取消訊號阻止新工作並讓活躍工作完成或安全回復 staging。
canary 通過後分批擴容,例如先 1 個分割區、再 3 個、再達到測得的安全並行。每次擴容都要觀察 完整一個目前增量週期。容量不足時,應提早調整期限、臨時資源或處理範圍,不能用犧牲生產新鮮度 掩蓋估算錯誤。
第四步:明確歷史回填與目前增量的寫入所有權
先在來源快照或日誌水位 W0 上重算歷史範圍,輸出到新版本。若目前管線只更正最近 7 天,可以讓 回填獨占較舊的 83 天,最近 7 天由目前管線繼續擁有,最後在新版本上重算或合併該重疊視窗。
若目前更正能觸及任意歷史訂單,採用「快照 + 增量追平」流程:
- 記錄
W0,回填只讀取不晚於W0的確定輸入。 - 目前管線繼續服務舊版本,同時把
W0之後的變更保留在可重播日誌。 - 90 個歷史分割區驗證後,記錄
W1,把(W0, W1]的變更按同一版本規則套用到新版本。 - 追平到允許的延遲後,短暫凍結發布指標或取得寫入柵欄,套用最後一段增量。
- 原子切換消費者到新版本,再讓目前管線以新版本為寫入目標。
這個方案要求變更日誌完整、順序規則穩定且切換操作真正具有原子性。若平台沒有原子檢視或 catalog 切換能力,就應使用明確維護視窗或帶舊分割區備份的交易式分批替換,並把可見中間狀態寫進風險 說明,不能口頭承諾無感切換。
第五步:分層驗證並把硬性門檻放在發布前
每個 staging 分割區完成後執行三層檢查:
- 結構與完整性: 結構相容、必填欄位非空、業務鍵唯一、日期邊界正確、90 個分割區無缺失或
重複。
- 來源對帳: 按日期、地區、幣別和狀態比較輸入輸出記錄數、唯一訂單數、稅前金額、稅費與
淨額;對彙總表還要保存可向下檢視的記錄差集。
- 業務與差異: 金額守恆、退款不超過可退金額、狀態轉換合法;新舊版本差異應集中在缺陷會
影響的訂單,未受影響切片不能無故變化。
列數相等的證據很弱:錯誤的 join 可能同時多算和漏算。除了彙總,還應按穩定鍵計算分桶校驗和, 抽查已知錯誤、邊界日期、延遲更正和刪除記錄,並讓財務或資料產品負責人確認修正方向。驗證查詢 本身需要版本控制,並保存閾值、實際值和執行結果。
全域發布門檻至少要求:清單顯示 90/90 VALIDATED;沒有活躍或失敗分割區;輸入快照、程式碼和 相依版本一致;追平水位達到 W1;硬性斷言全部通過;目前每日管線在回填期間仍滿足 45 分鐘 P95; 負責人完成簽核。任何一項失敗都保持舊版本可見。
第六步:一次切換、持續觀察、快速回復
發布前保存舊讀取指標和輸出版本。切換操作只改變穩定檢視或 catalog 指標,不在切換時重新搬運 180 TB。切換後立即執行一組消費者查詢,檢查關鍵儀表板、下游工作、查詢延遲和最近增量寫入; 觀察期內持續比較新舊版本的關鍵指標。
若唯一鍵、金額對帳、目前新鮮度或消費者查詢失敗,停止向新版本發布並切回舊指標。保留失敗版本、 清單和驗證證據供調查,不要就地修改後偽裝成同一個版本。修正輸入或程式碼後建立新的執行規格, 重用已經證明可信且版本一致的分割區;版本不同的分割區必須重算。
監控面板應同時顯示:已處理與剩餘 TB、各狀態分割區數、吞吐、預計完成時間、重試和校驗失敗、 來源端限流、運算池排隊、目標提交延遲,以及目前管線的 P50/P95 新鮮度。告警要帶 backfill_id、分割區、程式碼版本、失敗門檻和負責人,值班人員才能判斷是降低並行、重試分割區 還是停止整批發布。
高品質示範回答
「我會先把這次回填凍結成一個版本化執行:90 個 business_date、原始快照和水位 W0、程式碼 SHA、稅率維度表版本、目標表版本以及驗收閾值。按一天一個工作寫入隔離 staging,用清單記錄 PENDING/RUNNING/VALIDATED/PUBLISHED 和每次嘗試。轉換只使用邏輯日期。封閉分割區採用完整 建立後替換;會被延遲更正觸及的訂單按穩定主鍵和來源版本 MERGE,舊版本不得覆蓋新版本。」
「180 TB 在 5 天內要求原始讀取平均至少約 417 MB/s,這還沒有計算重試和驗證。我會先跑一個有 代表性的分割區,量出端到端吞吐和各階段峰值,再逐級增加並行。回填放在獨立低優先級資源池, 同時限制來源讀取、目標寫入和排程並行。控制器以目前增量的 P95 新鮮度為保護訊號,接近 45 分鐘 就停止領取新分割區,恢復後再緩慢加速。」
「並行正確性上,我從 W0 的快照產生新版本,舊版本繼續由目前管線服務;歷史分割區完成後記錄 W1,把 (W0, W1] 的更正重播到新版本,最後用短柵欄追平並原子切換指標。發布前必須滿足 90/90 分割區、主鍵唯一、來源金額對帳、業務不變量、新舊差異可解釋和生產新鮮度達標。舊版本 保留到觀察期結束;若硬性門檻或消費者查詢失敗,直接切回舊指標並保留失敗版本調查。」
常見錯誤
- 直接把排程並行設成最大 → 來源、shuffle、目標提交或每日工作會先成為瓶頸 → **從單一分割區
基準、吞吐下限和生產 SLO 推導並行,並動態降低速率。**
- 把工作重試等同於等冪 → 排程器只會再次執行,盲目附加仍會重複資料 → **使用確定輸入和邏輯
日期,按分割區替換或按穩定鍵與版本合併。**
- 歷史和目前工作同時寫同一分割區 → 晚完成的舊計算可能覆蓋新更正 → **劃分分割區所有權,
或用 W0/W1 增量追平和明確版本順序。**
- 90 個工作成功就發布 → 成功狀態不證明記錄完整、金額正確或差異合理 → **設定分割區、來源、
業務、差異和消費者五類門檻。**
- 直接覆蓋線上表再驗證 → 驗證失敗時只能再次大規模重算 → **先寫版本化輸出,驗證後一次切換
並保留舊指標。**
- 只比較總列數 → 重複和遺漏可能互相抵銷 → **同時比較唯一鍵、分桶校驗和、金額、狀態分布
和記錄差集。**
- 在歷史轉換裡呼叫
now()→ 兩次重跑會得到不同分割區語意 → **把邏輯日期、輸入快照和
相依版本都作為執行參數。**
- 失敗後重跑全部 180 TB → 擴大成本和風險,也丟失已驗證進度 → **用分割區清單從失敗單元
恢復,版本變化時才重算受影響分割區。**
追問及應對
追問一:來源系統沒有不可變快照,怎樣保證回填可重複?
優先在開始前匯出帶版本的歷史快照,或記錄資料庫快照位置、CDC 日誌位置和每個物件的版本 ID。 若只能讀取會變化的來源表,就把讀取時間、水位和逐分割區校驗和寫進清單,並將執行期間的變更 持續捕捉到日誌,隨後追平。無法重建當時輸入時,要揭露可重複性的缺口,不能聲稱兩次執行必然 相同。
追問二:事實表依賴也被修正的 SCD 維度表,先回填誰?
先從資料血緣產生受影響子圖,按拓撲順序建立新的維度表版本,再讓事實表按事件時間與該版本做 as-of join,最後重建彙總和資料市集。所有層共享同一個回填版本標識;舊維度表與新事實表不能 混合發布。驗證要涵蓋維度表業務鍵、生效區間不重疊、事實外鍵命中率和關鍵彙總對帳。
追問三:平台不支援原子表交換,怎樣發布?
優先把新結果寫成獨立版本表,並讓消費者透過穩定檢視讀取;若檢視定義可以原子替換,只切檢視。 若連這項能力也沒有,就選擇帶舊分割區備份的交易式小批替換或明確維護視窗,暫停相關讀寫後 完成切換與驗收。方案應寫出中間狀態的可見性和回復時間,不能把多步覆蓋描述成原子操作。
追問四:新舊版本列數和總金額都相同,還需要什麼驗證?
需要。按穩定業務鍵計算分桶校驗和並檢查記錄差集;比較地區、幣別、訂單狀態、稅率級距和邊界 日期的分布;驗證已知錯誤樣本確實改變、未受影響樣本保持不變;檢查主鍵、參照完整性、狀態演進 和退款上限。相等的總數可能由一筆多算和另一筆漏算抵銷。
追問五:應該從最早日期還是最近日期開始?
取決於相依和業務價值。若後一分割區依賴前一分割區狀態,必須正序;若各分割區獨立且希望盡快 修復近期報表,可以倒序。無論順序如何,發布門檻仍按完整範圍判斷,除非產品明確批准分階段發布, 並為每個階段定義獨立版本、消費者範圍和回復邊界。