題幹與適用場景
題目考察資料工程師能否把「資料要新」變成可驗證的端到端承諾。假設訂單事件從業務庫進入串流或批次管道,最後供銷售看板使用;任務成功不代表最新事件已可查詢。回答應區分事件發生、到達、處理完成與消費者可見時間,並說明遲到資料、回填和業務降級。
面試官考察點
強回答會先問業務能容忍多久的陳舊,再定義 freshness SLI/SLO、統計視窗和錯誤預算;接著沿每個階段記錄時間戳,區分上游無資料、傳輸積壓、處理變慢和查詢層延遲。它會把 source freshness 與最終產品 freshness 分開,提供分層告警、可信快照、重播和復盤指標,而不是只看 DAG 綠燈。
回答前需要釐清的問題
- 看板要求「最後一筆事件」還是完整時間窗?可容忍多久陳舊,按 p95、p99 還是最大值承諾?
- 時間戳由誰產生,時鐘是否同步?事件可能重複、亂序或遲到多久?
- 監控對象是原始來源、主題、模型、實體化表還是最終查詢結果?
- 過期時可以顯示上一份快照嗎?結算、風控等不可逆動作是否必須暫停?
- 需要支援回填、重播、跨時區和多租戶嗎?告警 owner 與升級窗口是什麼?
30 秒回答框架
「我先把業務承諾寫成 SLO,例如最近 30 天內 99% 的訂單事件在發生後 10 分鐘內可被看板查詢。每筆記錄保留 event、ingest、process 和 visible 時間,計算端到端 age 及各階段耗時,並分別監控來源停更與處理積壓。超過閾值時先標記資料延遲,顯示上一份可信快照;不可逆鏈路隔離新資料。修復後透過冪等重播、對帳和 SLO 復盤關閉事件。」
分步深入解答
第一步:把業務承諾寫成 SLO
明確「可見」的定義,例如事件進入查詢層並通過品質門禁後才算可用。用視窗化成功率表達目標,避免只寫平均延遲;同時記錄分母、排除項和錯誤預算。
第二步:統一時間語意
事件時間表示業務發生,攝取時間表示平台收到,處理完成時間表示模型產出,visible 時間表示消費者可讀。所有時間使用 UTC,並檢查時鐘偏差。若只有 updated_at,必須標註它不能代表端到端新鮮度。
第三步:拆解延遲預算
為 source、transport、queue、transform、warehouse apply 和 query cache 分配預算。端到端延遲可寫成 visibleat - eventat,階段延遲用相鄰時間戳相減;p95 超預算時即可定位瓶頸。
第四步:處理無資料與遲到資料
沒有新事件時不能把舊資料誤判為健康。以 source heartbeat 或最大已知事件時間監控停更,並單獨記錄 watermark。遲到事件在允許視窗內補算;超窗資料進隔離區並觸發對帳。
第五步:設計指標、標籤和告警
最小指標包括 freshness age、各階段延遲、watermark lag、積壓量、成功可見事件比例和快照年齡。標籤包含資料集、租戶、分割區、管道版本和 owner;告警按 warning、SLO burn 和 page 分級。
第六步:連接品質與血緣
新鮮不等於正確。把缺失率、重複率、主鍵衝突、模式變化和業務對帳結果與 freshness 關聯,沿血緣識別受影響看板。source freshness 不能代替最終產品測量。
第七步:設計降級、修復與回放
可逆展示可顯示上一份可信快照並標記最後更新時間;結算、權限、風控等不可逆動作應暫停或隔離。保留原始事件,修復後用冪等鍵重播、重算受影響視窗,再與來源對帳。
第八步:用演練證明方案有效
模擬上游停更、消費者積壓、倉庫 apply 變慢和遲到事件。確認每種故障都能在正確階段告警,runbook 給出 owner、升級時間和安全恢復步驟。復盤首次發現位置、誤報率、恢復時間與錯誤預算消耗。
可執行的檢查偽代碼
for dataset in monitored_datasets:
source_age = now - dataset.source_max_event_time
product_age = now - dataset.product_max_visible_event_time
if source_age > dataset.source_slo:
alert("source_stale", dataset.owner)
if product_age > dataset.product_slo:
serve_last_trusted_snapshot(dataset)設計取捨與邊界
| 決策 | 選擇 | 原因 |
|---|---|---|
| 目標統計 | p95/p99 + 成功率 | 避免平均值掩蓋長尾 |
| 時間基準 | event time 為主,visible time 為終點 | 反映使用者真正等待的年齡 |
| 告警頻率 | 檢查間隔小於 SLO 視窗 | 及時發現並控制成本 |
| 降級 | 快照僅用於可逆展示 | 避免陳舊資料驅動不可逆動作 |
來源沒有更新時應報 source 停更,不應懲罰處理任務;產品表更新正常但查詢快取過期時應報 serving 層。SLO 也不能脫離完整性:一張快速但缺半數訂單的表不算達標。
落地計畫與證據
先選一個消費者少、業務影響明確的資料集。登記 owner 和時間語意,採集四類時間戳,建立 source 與 product 兩層 freshness 檢查,再接入快照降級和回放 runbook。dbt Labs 建議監控頻率與 SLA 對齊;Google Cloud CDC 文件則用應用延遲分位數評估最新資料可見性。
試點的退出條件
連續多個視窗中,SLO 成功率、首次發現位置和恢復時間可計算;故障演練能通知正確 owner;快照不會被誤用於不可逆決策;遲到和回放結果能與來源對帳。
如何證明收益不是巧合
比較試點前後 freshness 違約率、下游發現次數、p95 端到端延遲、錯誤預算消耗、恢復時間和快照使用時長,同時控制發布量和上游負載。若誤報率升高,修正閾值或分區標籤。
常見誤區與追問
只看任務成功狀態
任務成功只說明程式回傳成功,不能證明來源有新資料、所有分割區已處理或最終查詢可見。必須測量資料時間和產品時間。
用處理時間代替事件時間
處理很快但事件已在來源滯留數小時,處理時間會掩蓋陳舊。應保留 event time,並報告 source age 與端到端 age。
只設定一個全域閾值
即時風控、日報和探索分析的可接受延遲不同。按資料集、消費者和業務動作分層 SLO。
如何處理時鐘漂移?
統一 UTC,監控節點時鐘偏差;不可信時間戳應標為不確定,使用攝取時間和平台單調時間輔助。
遲到資料已經發布怎麼辦?
標記受影響視窗,隔離超窗事件,按冪等鍵重播並重算派生表,完成來源對帳後更新報表並保留審計記錄。
告警一直響但沒有事故怎麼辦?
檢查 SLO 是否與業務定義一致、分母是否包含無資料視窗、分區標籤是否遺失。用 burn-rate 和合併告警降低噪聲。