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 環境
|
大規模數據湖,高性能事務,多引擎協作
|
近實時數據湖,需要增量處理和低延遲更新
|
二、 選擇存儲格式的關鍵考量因素
- 工作負載類型 (Workload Type):
- 分析型查詢 (OLAP):優先選擇 列式格式 (Parquet, ORC)。這是絕大多數數倉場景的首選。
- 事務型/點查 (OLTP-like):如果需要頻繁的單條記錄更新/刪除,考慮 Delta Lake, Iceberg, Hudi。
- 流式處理 (Streaming):
- 源數據攝入:Avro (與 Kafka 集成好) 或 Parquet (如果寫入頻率不高)。
- 流式寫入目標:Delta Lake, Hudi, Iceberg 支持高效的流式寫入(
append和upsert)。
- 是否需要 ACID 事務:
- 需要:必須選擇支持 ACID 的格式。Delta Lake, Iceberg, Hudi 是當前主流選擇。它們能保證併發寫入時的數據一致性,避免文件損壞。
- 不需要:
Parquet或ORC可能滿足需求,但需自行處理併發寫入衝突(通常通過應用層鎖或批處理避免)。
- 模式演化需求 (Schema Evolution):
- 頻繁變更:如果數據源模式經常變化(如添加新字段、修改字段名),Avro 在行式格式中支持最好。對於列式格式,Delta Lake, Iceberg, Hudi 提供了強大的模式演化能力(如自動允許添加列)。
- 相對穩定:
Parquet和ORC的模式演化能力有限,適合模式穩定的場景。
- 更新與刪除 (Upsert/Delete) 能力:
- 需要:傳統
Parquet/ORC文件無法高效更新單條記錄,需要重寫整個文件或分區,成本高昂。Delta Lake, Iceberg, Hudi 通過維護索引或日誌,支持高效的MERGE INTO,UPDATE,DELETE操作。
- 增量處理需求:
- 需要:如果下游任務(如數據同步、機器學習特徵生成)只需要處理自上次以來的變更數據,Hudi (CDC 集成好) 和 Delta Lake/Iceberg (通過版本/時間戳獲取增量快照) 是理想選擇。
- 生態系統與工具兼容性:
- 廣泛兼容性:
Parquet是事實上的開放標準,被幾乎所有大數據工具支持,是安全、通用的選擇。 - 特定平台:
- Databricks 環境:Delta Lake 是原生首選,集成度最高。
- Hive 生態:ORC 有深厚基礎。
- 多引擎協作:Iceberg 設計上強調開放性和多引擎(Spark, Flink, Presto/Trino, Hive)的互操作性,是很好的選擇。
- 性能與成本:
- 讀取性能:
Parquet和ORC通常提供最佳的列式讀取性能和壓縮率。 - 寫入性能:
Avro寫入通常較快(行式追加)。Parquet/ORC寫入需要緩衝和排序,可能稍慢。Delta Lake/Hudi/Iceberg的寫入開銷取決於其事務日誌和索引機制。 - 存儲成本:
Parquet和ORC壓縮率高,存儲成本低。Avro壓縮率也高。開放表格式本身不增加存儲,但其元數據和日誌文件會佔用少量額外空間。
三、 推薦實踐與分層策略
- ODS (操作數據存儲) 層:
- 首選:Avro 或 JSON。
- 理由:最接近源系統,模式可能不穩定,需要良好的序列化和模式演化支持。適合從 Kafka 等流系統攝入。
- 備選:如果模式穩定且寫入非實時,也可用
Parquet。
- DWD (數據倉庫明細) / DWS (數據倉庫彙總) 層:
- 首選:
- 通用/開放性優先:Parquet (如果不需要事務/更新) 或 Iceberg (需要事務/更新/多引擎)。
- Databricks 環境:Delta Lake。
- Hive 生態:ORC。
- 理由:這是核心分析層,需要高性能查詢和高存儲效率。列式格式是必須的。如果需要
UPSERT(如處理遲到數據) 或強一致性,開放表格式是更好的選擇。
- ADS (應用數據服務) 層:
- 首選:Parquet 或 Delta Lake/Iceberg。
- 理由:為下游應用(BI 報表、API)提供服務,查詢模式明確,性能要求高。
Parquet是成熟穩定的選擇。如果 ADS 層需要頻繁更新(如實時大屏),則Delta Lake/Iceberg更合適。
- 數據湖 (Data Lake) 基礎:
- 強烈推薦:將 Parquet 作為數據湖的事實標準。
- 理由:最大化的兼容性、高性能、低成本。即使上層使用 Delta Lake/Iceberg,它們通常也以 Parquet 作為底層數據文件格式。
- 混合使用策略:
- ODS: Avro (流式攝入)
- DWD/DWS: Delta Lake (在 Databricks 上,支持事務和 upsert)
- ADS: Parquet (為外部 BI 工具提供高性能訪問)
- 歸檔: Parquet (應用雲存儲生命週期策略)
四、 最佳實踐
- 優先考慮列式存儲:除非有強理由(如必須的行式處理),否則默認選擇列式格式(Parquet, ORC, Delta, Iceberg, Hudi)。
- 擁抱開放標準:
Parquet是兼容性最好的選擇。Iceberg作為開放表格式,有助於避免供應商鎖定。 - 評估事務需求:如果數據管道複雜、涉及多源寫入或需要處理數據修正,開放表格式(Delta, Iceberg, Hudi)帶來的 ACID 保證和
MERGE INTO能力價值巨大。 - 利用壓縮:無論選擇哪種格式,都應啓用合適的壓縮算法(如
ZSTD在壓縮比和速度間平衡較好,SNAPPY速度快)。 - 分區與分桶 (Partitioning & Bucketing):
- 分區:按高基數、常用於過濾的字段分區(如
date,region),能大幅減少掃描數據量。 - 分桶:對特定字段(如
user_id)進行哈希分桶,可優化JOIN和AGGREGATE性能。Delta Lake/Iceberg/Hudi 對分區演化的支持更好。
- 文件大小優化:避免產生大量小文件(影響讀取性能)或過大的文件(影響並行度)。目標文件大小通常在 128MB - 1GB 之間。使用
OPTIMIZE(Delta Lake),COMPACTION(Hudi),RewriteDataFiles(Iceberg) 等命令合併小文件。 - 元數據管理:確保數據目錄(如 AWS Glue, Azure Purview, Apache Atlas)能正確解析所選格式的元數據(Schema, 分區信息)。
總結:
- 通用王者:Parquet 憑藉其卓越的性能、極高的兼容性和成熟的生態,是絕大多數分析場景的安全且高效的選擇。
- 現代化數據湖:當需要 ACID 事務、可靠更新、時間旅行或增量處理時,Delta Lake, Iceberg, Hudi 這些開放表格式是必然趨勢。它們在 Parquet/ORC 的基礎上,提供了強大的元數據管理和數據操作能力。
- 流式與源數據:Avro 在處理事件流和需要強模式演化的場景中依然不可替代。
- Hive 生態:ORC 在傳統 Hive 環境中仍有重要地位。
最終選擇應基於您的具體技術棧(是否使用 Databricks?)、業務需求(是否需要 upsert?)、團隊技能和對開放性/供應商鎖定的考量。在實踐中,Parquet 作為基礎,結合 Delta Lake 或 Iceberg 處理複雜場景,是一種非常強大和靈活的組合。