資料工程面試:如何設計可稽核的資料品質隔離管道?
題干與適用場景
上游每天傳送 2 億筆訂單事件,約 0.2% 可能缺少必填欄位、型別解析失敗或違反業務規則。有效事件要繼續進入事實表與下游指標;錯誤事件不能靜默丟棄,修復後還要能從原始輸入重播,並保證同一事件不會重複計入。
本文採用批次與串流共用的約束:每筆輸入有穩定 event_id,原始 payload 保存不可變副本;品質規則按 schema 版本發布;隔離記錄保留失敗原因、規則版本與重試狀態。核心是資料工程中的分流、可觀測性與復原,不是特定 Spark API。
面試官考察點
- 能否把解析失敗、欄位缺失與業務校驗失敗分成可行動的錯誤類型。
- 是否保留原始證據、規則版本與 lineage,支援稽核與重播。
- 是否區分
fail-fast、drop、redirect/quarantine的適用情境。 - 是否用冪等鍵、去重狀態與輸出版本避免重複計數。
- 是否設計品質指標、告警門檻、人工修復與重播門禁。
- 是否說明毒性資料、PII、保留期限與隔離區存取控制。
回答前需要釐清的問題
- 0.2% 是可接受的業務缺陷比例,還是超標就必須阻止發布?這決定門禁是閾值還是零容忍。
- 事件是否可能補發、亂序或重複?若可能重複,
event_id必須成為冪等邊界。 - 規則失敗可以自動修復,還是一定要人工確認?這會改變重播佇列與審批流程。
- 下游指標能否接受延遲或更正?若不能,隔離修復後需要補償分割區與版本化報表。
- 原始 payload 是否包含個人資料?這會改變加密、脫敏、存取與刪除策略。
30 秒回答框架
我把管道分成原始不可變層、解析層、規則驗證層,以及有效與隔離兩個輸出。解析失敗與規則失敗都產生含 eventid、schema 版本、規則版本、原因碼與原始引用的 quarantine 記錄;有效事件用冪等寫入進入事實表。隔離區提供修復、審批與重播佇列,重播仍使用同一 eventid 並在目標分割區去重。監控有效率、各原因碼比例、隔離年齡與重播成功率,門禁按業務 SLO 決定阻斷或告警。
分步驟深入解答
1. 先保存原始證據
原始物件儲存或日誌層依批次、來源與接收時間分割,內容不可變並帶校驗和。解析任務只追加處理狀態,不覆蓋原文。如此規則升級、解析器修復或供應商爭議都能從同一輸入重現結果;原始層與隔離層要分離權限,避免支援人員直接修改事實資料。
2. 將失敗分層並保留原因
先做位元組與格式解析,再做 schema 型別與必填欄位檢查,最後做跨欄位與業務規則檢查。每次失敗寫入結構化 reasoncode,例如 MALFORMEDJSON、MISSINGORDERID、INVALID_CURRENCY。一筆資料可以有多個原因,但要保存首次失敗階段與規則版本,避免修復後無法解釋歷史結果。
quarantine_record = {
event_id, source_batch, raw_uri, payload_hash,
schema_version, rule_version, failed_stage,
reason_codes, first_seen_at, status
}Spark 的檔案讀取選項可以記錄壞檔或忽略損壞檔案,但「繼續執行」不等於業務資料安全;題目要求把可復原的資料顯式寫入隔離管道,而不是只開啟忽略選項。
3. 選擇 fail、drop 或 quarantine
基礎設施不可讀、簽章不可信或可能污染整批的資料應 fail,讓批次重試並保留告警。可定位到單筆且不影響其他事件的錯誤應 quarantine,讓有效資料繼續。只有經業務負責人批准、資料不可復原且有稽核要求時才 drop;drop 必須計數並可追溯,不能把靜默遺失當成成功。
4. 有效寫入與冪等邊界
以 event_id 加來源版本建立唯一鍵,事實表寫入使用冪等 upsert 或去重日誌。隔離資料重播時先檢查目標表是否已接受該事件,再決定跳過、更新或寫入補償版本。對訂單金額這類可更正事實,不要直接覆蓋舊值;應寫入更正事件,讓下游按版本或有效時間重算。
5. 修復、審批與重播
修復工具只能產生新 payload 或修復補丁,不能修改原始層。每次修復記錄操作者、原因、輸入雜湊與規則版本,並進入審批佇列。重播 worker 從隔離狀態讀取,重新執行完整驗證鏈;成功後把狀態從 QUARANTINED 原子更新為 REPLAYED,失敗則增加嘗試次數與下次時間。並行重播用租約或資料庫鎖避免同一事件同時提交。
6. 品質指標與發布門禁
至少監控總接收量、有效率、每個 reason_code 比率、隔離區年齡分位數、重播成功率、重複事件數與下游更正量。門禁按規則嚴重度分層:簽章錯誤可零容忍,缺少選填欄位只告警;0.2% 也不能直接當成正常,要和歷史基線、來源與業務損失一起判斷。超過門檻時凍結下游發布或切換上一版規則,並保留人工放行記錄。
7. 保留、隱私與失敗復原
隔離區只保留修復所需的最小原始欄位,敏感 payload 加密並限制存取;保留期限與刪除要求要能對應 event_id 與原始物件。佇列、元資料表與物件儲存要分別備份。若下游寫入成功但狀態更新失敗,靠唯一鍵重試;若狀態已標記重播但寫入未確認,透過提交日誌或目標表校驗復原,不能憑 worker 回傳值猜測成功。
高品質示範回答
我會先確認缺陷是否可接受、事件是否會重複補發,以及訂單更正能否延遲到報表。管道保存不可變原始層,解析、schema 與業務規則分階段執行;單筆可復原錯誤寫入 quarantine,基礎設施或安全錯誤阻斷批次。隔離記錄包含事件冪等鍵、原始引用、規則版本、原因碼與狀態。有效事件冪等寫入事實表,修復工具產生新 payload 並經過審批,重播再次執行完整驗證,成功後原子標記已重播。監控有效率、原因碼、隔離年齡、重播率與重複計數,按嚴重度設定門禁。如此既不會讓少量錯誤阻塞整批,也不會把異常隱藏成資料正常。
常見錯誤
- 開啟
ignoreCorruptFiles就算完成 → 解析能繼續但資料可能永久消失 → 把可復原資料寫入帶原因碼的隔離區。 - 錯誤資料直接放在可編輯表 → 原始證據被竄改 → 原始層不可變,修復只產生新版本。
- 重播直接再插入事實表 → 重複計入指標 → 使用
event_id唯一鍵與提交日誌做冪等。 - 所有錯誤都阻斷整批 → 少量壞資料拖垮新鮮度 → 按階段、嚴重度與隔離能力選擇 fail 或 quarantine。
- 只統計失敗數量 → 無法定位來源與規則回歸 → 按原因碼、schema 版本、來源與時間分布監控。
- 修復後繞過驗證 → 新 payload 可能引入第二個錯誤 → 重播必須重新執行完整驗證鏈。
追問及應對
隔離比例突然從 0.2% 升到 8%,要不要繼續發布?
先按原因碼與來源拆分。若是單一供應商的可復原欄位缺失,暫停該來源並繼續處理其他來源;若是 schema 解析或簽章錯誤,凍結下游發布並回滾規則版本。閾值要綁定業務損失與歷史基線,不能只看絕對百分比。
如何保證重播不會改變已結算訂單?
把原始事件和更正事件分開,事實表保存版本或有效時間。結算快照鎖定輸入代;修復事件進入補償流程,由財務規則決定是否產生調整單,而非靜默覆蓋歷史金額。
隔離區也含 PII,支援人員如何排查?
預設只顯示脫敏欄位與原因碼,原始 payload 用短期授權存取並記錄稽核日誌。刪除要求透過 event_id 關聯原始物件、隔離記錄與衍生索引,刪除後保留不可逆的稽核摘要。
worker 在目標寫入後崩潰,狀態仍是待重播怎麼辦?
重試前按冪等鍵檢查目標表與提交日誌;已存在就補寫狀態,不再重複業務副作用。若兩者都沒有就重新提交。狀態遷移使用可重試的條件更新,避免把未知結果標記成失敗或成功。
什麼時候應該丟棄而不是長期隔離?
只有資料不可復原、無合規保留要求且業務方明確接受損失時才丟棄。即使丟棄,也要保存數量、原因、批次與策略版本的稽核摘要,並讓監控和資料品質報告可見。