5.1.5 數據倉庫存儲格式選擇

選擇合適的存儲格式,需要在查詢性能、寫入性能、存儲成本、壓縮效率、模式演化支持、生態系統兼容性等多個維度進行權衡。現代數據倉庫(尤其是基於數據湖的架構)提供了多種列式存儲格式作為首選。

一、 核心存儲格式對比

以下是目前主流的、適用於數據倉庫場景的存儲格式:

特性/格式

Parquet

ORC

Avro

Delta Lake

Iceberg

Hudi

數據組織

列式 (Columnar)

列式 (Columnar)

行式 (Row-based)

列式 (基於 Parquet)

列式 (基於 Parquet/ORC)

列式 (基於 Parquet)

主要優勢

高壓縮比,極佳的分析查詢性能,廣泛支持

高壓縮比,優秀的查詢性能,Hive 生態深度集成

強模式演化,高效序列化,適合流式寫入

ACID 事務,模式演化,時間旅行,統一批流

開放表格式,高性能,大規模事務,模式演化

增量處理,近實時,upsert/delete

壓縮支持

優秀 (SNAPPY, GZIP, ZSTD, LZO)

優秀 (ZLIB, SNAPPY, ZSTD, LZO)

優秀 (SNAPPY, DEFLATE)

繼承 Parquet

繼承底層格式

繼承 Parquet

模式演化

有限 (添加列,修改元數據)

有限 (添加列,修改元數據)

極佳 (添加、刪除、重命名字段,類型兼容變更)

優秀 (自動/手動模式演化)

優秀 (豐富的模式演化操作)

優秀 (支持模式變更)

ACID 事務

❌ (文件級)

❌ (文件級)

❌ (文件級)

✅ (核心特性)

✅ (核心特性)

✅ (核心特性)

時間旅行 (Time Travel)




✅ (版本控制)

✅ (快照)

✅ (增量快照)

更新/刪除 (Upsert/Delete)

❌ (需重寫文件)

❌ (需重寫文件)

❌ (需重寫文件)

✅ (MERGE INTO, DELETE)

✅ (MERGE INTO, DELETE)

✅ (UPSERT, DELETE)

增量處理

❌ (全量)

❌ (全量)

❌ (全量)

✅ (通過版本/時間戳)

✅ (增量快照)

✅ (核心優勢,記錄級增量)

生態系統支持

極其廣泛 (Spark, Flink, Hive, Presto/Trino, Redshift, Snowflake, BigQuery, Databricks, Athena, Impala)

廣泛 (Hive, Spark, Presto/Trino, Impala, Redshift Spectrum)

廣泛 (Kafka, Spark, Flink, Hive)

廣泛 (Spark, Databricks, Flink, Presto/Trino, Snowflake*, BigQuery*)

廣泛 (Spark, Flink, Presto/Trino, Hive, Snowflake*, BigQuery*)

廣泛 (Spark, Flink, Presto/Trino)

典型應用場景

通用分析,數據湖標準,高吞吐讀取

Hive 生態,高吞吐分析

事件流,日誌數據,需要頻繁模式變更的源數據

需要事務和可靠性的數據湖,統一數據架構,Databricks 環境

大規模數據湖,高性能事務,多引擎協作

近實時數據湖,需要增量處理和低延遲更新

二、 選擇存儲格式的關鍵考量因素

  1. 工作負載類型 (Workload Type):
  1. 分析型查詢 (OLAP):優先選擇 列式格式 (Parquet, ORC)。這是絕大多數數倉場景的首選。
  2. 事務型/點查 (OLTP-like):如果需要頻繁的單條記錄更新/刪除,考慮 Delta Lake, Iceberg, Hudi。
  3. 流式處理 (Streaming):
  • 源數據攝入:Avro (與 Kafka 集成好) 或 Parquet (如果寫入頻率不高)。
  • 流式寫入目標:Delta Lake, Hudi, Iceberg 支持高效的流式寫入(appendupsert)。
  1. 是否需要 ACID 事務:
  1. 需要:必須選擇支持 ACID 的格式。Delta Lake, Iceberg, Hudi 是當前主流選擇。它們能保證併發寫入時的數據一致性,避免文件損壞。
  2. 不需要:ParquetORC 可能滿足需求,但需自行處理併發寫入衝突(通常通過應用層鎖或批處理避免)。
  1. 模式演化需求 (Schema Evolution):
  1. 頻繁變更:如果數據源模式經常變化(如添加新字段、修改字段名),Avro 在行式格式中支持最好。對於列式格式,Delta Lake, Iceberg, Hudi 提供了強大的模式演化能力(如自動允許添加列)。
  2. 相對穩定:ParquetORC 的模式演化能力有限,適合模式穩定的場景。
  1. 更新與刪除 (Upsert/Delete) 能力:
  1. 需要:傳統 Parquet/ORC 文件無法高效更新單條記錄,需要重寫整個文件或分區,成本高昂。Delta Lake, Iceberg, Hudi 通過維護索引或日誌,支持高效的 MERGE INTOUPDATEDELETE 操作。
  1. 增量處理需求:
  1. 需要:如果下游任務(如數據同步、機器學習特徵生成)只需要處理自上次以來的變更數據,Hudi (CDC 集成好) 和 Delta Lake/Iceberg (通過版本/時間戳獲取增量快照) 是理想選擇。
  1. 生態系統與工具兼容性:
  1. 廣泛兼容性:Parquet 是事實上的開放標準,被幾乎所有大數據工具支持,是安全、通用的選擇。
  2. 特定平台:
  • Databricks 環境:Delta Lake 是原生首選,集成度最高。
  • Hive 生態:ORC 有深厚基礎。
  • 多引擎協作:Iceberg 設計上強調開放性和多引擎(Spark, Flink, Presto/Trino, Hive)的互操作性,是很好的選擇。
  1. 性能與成本:
  1. 讀取性能:ParquetORC 通常提供最佳的列式讀取性能和壓縮率。
  2. 寫入性能:Avro 寫入通常較快(行式追加)。Parquet/ORC 寫入需要緩衝和排序,可能稍慢。Delta Lake/Hudi/Iceberg 的寫入開銷取決於其事務日誌和索引機制。
  3. 存儲成本:ParquetORC 壓縮率高,存儲成本低。Avro 壓縮率也高。開放表格式本身不增加存儲,但其元數據和日誌文件會佔用少量額外空間。

三、 推薦實踐與分層策略

  1. ODS (操作數據存儲) 層:
  1. 首選:Avro 或 JSON。
  2. 理由:最接近源系統,模式可能不穩定,需要良好的序列化和模式演化支持。適合從 Kafka 等流系統攝入。
  3. 備選:如果模式穩定且寫入非實時,也可用 Parquet
  1. DWD (數據倉庫明細) / DWS (數據倉庫彙總) 層:
  1. 首選:
  • 通用/開放性優先:Parquet (如果不需要事務/更新) 或 Iceberg (需要事務/更新/多引擎)。
  • Databricks 環境:Delta Lake。
  • Hive 生態:ORC。
  1. 理由:這是核心分析層,需要高性能查詢和高存儲效率。列式格式是必須的。如果需要 UPSERT (如處理遲到數據) 或強一致性,開放表格式是更好的選擇。
  1. ADS (應用數據服務) 層:
  1. 首選:Parquet 或 Delta Lake/Iceberg。
  2. 理由:為下游應用(BI 報表、API)提供服務,查詢模式明確,性能要求高。Parquet 是成熟穩定的選擇。如果 ADS 層需要頻繁更新(如實時大屏),則 Delta Lake/Iceberg 更合適。
  1. 數據湖 (Data Lake) 基礎:
  1. 強烈推薦:將 Parquet 作為數據湖的事實標準。
  2. 理由:最大化的兼容性、高性能、低成本。即使上層使用 Delta Lake/Iceberg,它們通常也以 Parquet 作為底層數據文件格式。
  1. 混合使用策略:
  1. ODS: Avro (流式攝入)
  2. DWD/DWS: Delta Lake (在 Databricks 上,支持事務和 upsert)
  3. ADS: Parquet (為外部 BI 工具提供高性能訪問)
  4. 歸檔: Parquet (應用雲存儲生命週期策略)

四、 最佳實踐

  1. 優先考慮列式存儲:除非有強理由(如必須的行式處理),否則默認選擇列式格式(Parquet, ORC, Delta, Iceberg, Hudi)。
  2. 擁抱開放標準:Parquet 是兼容性最好的選擇。Iceberg 作為開放表格式,有助於避免供應商鎖定。
  3. 評估事務需求:如果數據管道複雜、涉及多源寫入或需要處理數據修正,開放表格式(Delta, Iceberg, Hudi)帶來的 ACID 保證和 MERGE INTO 能力價值巨大。
  4. 利用壓縮:無論選擇哪種格式,都應啓用合適的壓縮算法(如 ZSTD 在壓縮比和速度間平衡較好,SNAPPY 速度快)。
  5. 分區與分桶 (Partitioning & Bucketing):
  1. 分區:按高基數、常用於過濾的字段分區(如 dateregion),能大幅減少掃描數據量。
  2. 分桶:對特定字段(如 user_id)進行哈希分桶,可優化 JOINAGGREGATE 性能。Delta Lake/Iceberg/Hudi 對分區演化的支持更好。
  1. 文件大小優化:避免產生大量小文件(影響讀取性能)或過大的文件(影響並行度)。目標文件大小通常在 128MB - 1GB 之間。使用 OPTIMIZE (Delta Lake), COMPACTION (Hudi), RewriteDataFiles (Iceberg) 等命令合併小文件。
  2. 元數據管理:確保數據目錄(如 AWS Glue, Azure Purview, Apache Atlas)能正確解析所選格式的元數據(Schema, 分區信息)。

總結:

  • 通用王者:Parquet 憑藉其卓越的性能、極高的兼容性和成熟的生態,是絕大多數分析場景的安全且高效的選擇。
  • 現代化數據湖:當需要 ACID 事務、可靠更新、時間旅行或增量處理時,Delta Lake, Iceberg, Hudi 這些開放表格式是必然趨勢。它們在 Parquet/ORC 的基礎上,提供了強大的元數據管理和數據操作能力。
  • 流式與源數據:Avro 在處理事件流和需要強模式演化的場景中依然不可替代。
  • Hive 生態:ORC 在傳統 Hive 環境中仍有重要地位。

最終選擇應基於您的具體技術棧(是否使用 Databricks?)、業務需求(是否需要 upsert?)、團隊技能和對開放性/供應商鎖定的考量。在實踐中,Parquet 作為基礎,結合 Delta LakeIceberg 處理複雜場景,是一種非常強大和靈活的組合。