在這篇論文之前 — 它所降落的世界
大約 2014 到 2016 年間,在 S3 上放大型分析資料集的標準做法就是「一堆 Parquet 檔案」,頂多再用 Hive 風格的分割目錄整理成 mytable/date=2020-01-01/ 這種形式。這種做法只有純附加的掃描能用:一個要動到多個物件的工作會把中間狀態暴露給讀取者,工作崩潰就留下一張壞掉的表,而 S3 的 LIST 又是最終一致的,連寫入者自己剛放上去的物件都可能看不到。另一條路是 Snowflake 或 Hive ACID 這類封閉式引擎,把資料表的真實內容交給自己那套強一致的 metadata 服務管理,代價是必須常駐一個高可用服務、分割數到百萬級就成為瓶頸、每個引擎都要額外投入接連接器,而且被綁在單一供應商上。與此同時,GDPR 與單純的資料修補需求,正把全表更新硬塞給當初按不可變設計的資料集。作者提到,Databricks 雲端服務最初幾年,大約有一半的技術支援升級案件,都是雲端儲存策略造成的資料毀損、一致性或效能問題。
術語 — 依本篇論文的用法
- Delta table
- 物件儲存上的一個目錄,或者說一組共用同一段 key 前綴的物件,裡面放著 Parquet 資料物件與一個 _delta_log 子目錄。定義資料表包含哪些物件的是日誌,而不是對目錄做列舉。
- 交易日誌(_delta_log)
- 一連串以補零整數命名的 JSON 記錄,每筆內容是套用在前一個資料表版本上的 action 陣列;它是這張表的 WAL,也是唯一的事實來源。
- Checkpoint
- 把日誌壓縮合併到某個記錄編號、並移除多餘 action 之後寫成的 Parquet 檔,預設每 10 筆交易產生一次,讓讀取者不必從頭重播整份日誌。
- add 與 remove action
- 在資料表上掛上或拆下單一資料物件的日誌 action。add 可帶該物件的筆數與每欄 min/max、null 數;remove 則是帶時間戳的 tombstone,會保留到過了保留期限為止。
- Data skipping 統計
- 存在日誌裡(而非 Parquet footer 裡)的每物件 min/max、null 數與筆數,讓查詢規劃器用一次對 checkpoint 的欄式掃描就淘汰掉不相關物件,不必每個物件各做一次高延遲讀取。
- dataChange 旗標
- add 與 remove action 上的布林欄位;設為 false 表示這筆提交只是重排既有資料或補上統計,串流消費端因此可以略過壓縮合併與 Z-order 重寫。
- txn action
- 由應用程式提供的一組 (appId, version),與資料變更放在同一筆日誌記錄中原子提交;Structured Streaming 用它讓寫入具備冪等性,達成 exactly-once 語意。
- Z-ordering
- 沿著 Morton 空間填充曲線在多個欄位上重排記錄,使每個物件在每個所選維度上都只涵蓋很窄的值域,讓 min/max skipping 對多屬性過濾的效果倍增。
- Lakehouse
- 論文替這套結果取的名字:把交易、版本管理與稽核日誌等標準 DBMS 管理功能,直接套用在低成本雲端物件儲存上的資料表。