一、前言:三足鼎立的数据湖江湖
graph TB
subgraph "数据湖三巨头"
A[Hudi
Uber] --> A1["增量处理王者
CDC 场景首选"] B[Iceberg
Netflix] --> B1["开放标准之选
多引擎友好"] C[Delta Lake
Databricks] --> C1["Spark 生态融合
商业化成熟"] end
Uber] --> A1["增量处理王者
CDC 场景首选"] B[Iceberg
Netflix] --> B1["开放标准之选
多引擎友好"] C[Delta Lake
Databricks] --> C1["Spark 生态融合
商业化成熟"] end
选型困境:
graph LR
A[你] --> B{选择表格式}
B --> C["Hudi?
增量处理强"] B --> D["Iceberg?
开放标准"] B --> E["Delta Lake?
Spark 最配"] A --> F["到底选哪个?🤯"]
增量处理强"] B --> D["Iceberg?
开放标准"] B --> E["Delta Lake?
Spark 最配"] A --> F["到底选哪个?🤯"]
二、背景与定位
2.1 发展历程
timeline
title 数据湖表格式发展史
2016 : Uber 开发 Hudi
2017 : Netflix 开发 Iceberg
2017 : Databricks 开发 Delta Lake
2019 : Hudi 进入 Apache
2019 : Delta Lake 开源
2020 : Iceberg 成为 Apache 顶级项目
2020 : Hudi 成为 Apache 顶级项目
2023 : 三者功能趋同,竞争白热化
2.2 背景与设计目标
| 项目 | 公司 | 设计目标 | 核心场景 |
|---|---|---|---|
| Hudi | Uber | 解决增量更新问题 | CDC、实时数仓 |
| Iceberg | Netflix | 解决 PB 级表管理 | 大规模分析 |
| Delta Lake | Databricks | Spark 生态增强 | Lakehouse |
2.3 社区与生态
graph TB
subgraph "Hudi"
H1[Apache 顶级项目]
H2[GitHub 5k+ ⭐]
H3[国内社区活跃]
end
subgraph "Iceberg"
I1[Apache 顶级项目]
I2[GitHub 6k+ ⭐]
I3[国际社区强]
end
subgraph "Delta Lake"
D1[Linux 基金会]
D2[GitHub 7k+ ⭐]
D3[Databricks 主导]
end
三、架构对比
3.1 元数据架构
graph TB
subgraph "Hudi 元数据"
H1[Timeline
时间线] --> H2[Commit/DeltaCommit] H1 --> H3[Compaction] H1 --> H4[Clean] H5[Index] --> H6[Bloom/Bucket/HBase] end
时间线] --> H2[Commit/DeltaCommit] H1 --> H3[Compaction] H1 --> H4[Clean] H5[Index] --> H6[Bloom/Bucket/HBase] end
graph TB
subgraph "Iceberg 元数据"
I1[Metadata File] --> I2[Snapshot]
I2 --> I3[Manifest List]
I3 --> I4[Manifest File]
I4 --> I5[Data File]
end
graph TB
subgraph "Delta Lake 元数据"
D1[_delta_log/] --> D2[JSON Files
0-9] D2 --> D3[Checkpoint
每10个] D3 --> D4[Data Files] end
0-9] D2 --> D3[Checkpoint
每10个] D3 --> D4[Data Files] end
3.2 元数据对比
| 维度 | Hudi | Iceberg | Delta Lake |
|---|---|---|---|
| 元数据格式 | Timeline + Index | 三层架构 | JSON + Checkpoint |
| 元数据位置 | .hoodie 目录 | metadata 目录 | _delta_log 目录 |
| 索引机制 | 内置多种索引 | 列级统计 | 文件级统计 |
| Catalog 依赖 | 可选 | 必须(推荐) | 可选 |
3.3 文件布局对比
# Hudi 文件布局
hudi_table/
├── .hoodie/
│ ├── hoodie.properties
│ └── 20240115100000.commit
└── 2024/01/15/
├── file_1.parquet
└── .file_1.log.1
# Iceberg 文件布局
iceberg_table/
├── metadata/
│ ├── v1.metadata.json
│ └── snap-xxx.avro
└── data/
└── date=2024-01-15/
└── 00000-0-xxx.parquet
# Delta Lake 文件布局
delta_table/
├── _delta_log/
│ ├── 00000000000000000000.json
│ └── 00000000000000000010.checkpoint.parquet
└── part-00000-xxx.parquet四、核心能力对比
4.1 功能矩阵
graph TB
subgraph "核心能力对比"
A[ACID 事务] --> A1["All ✅"]
B[时间旅行] --> B1["All ✅"]
C[Schema 演进] --> C1["All ✅"]
D[分区演进] --> D1["Iceberg ✅✅✅
Hudi ✅
Delta ✅"] E[增量查询] --> E1["Hudi ✅✅✅
Iceberg ✅✅
Delta ✅"] F[索引能力] --> F1["Hudi ✅✅✅
Iceberg ✅✅
Delta ✅✅"] end
Hudi ✅
Delta ✅"] E[增量查询] --> E1["Hudi ✅✅✅
Iceberg ✅✅
Delta ✅"] F[索引能力] --> F1["Hudi ✅✅✅
Iceberg ✅✅
Delta ✅✅"] end
4.2 详细功能对比表
| 功能 | Hudi | Iceberg | Delta Lake |
|---|---|---|---|
| ACID 事务 | ✅ | ✅ | ✅ |
| 时间旅行 | ✅ | ✅ | ✅ |
| 增量查询 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| Schema 演进 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 分区演进 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 隐藏分区 | ❌ | ✅ | ❌ |
| COW/MOR | ✅ 两种 | ✅ 两种 | ✅ 仅 COW |
| 内置索引 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| Compaction | ✅ 内置 | ✅ 内置 | ✅ OPTIMIZE |
| Clustering | ✅ | ✅ | ✅ Z-Order |
| CDC 支持 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
4.3 引擎支持对比
graph TB
subgraph "Spark 支持"
S1[Hudi] --> S1a["✅ 一等公民"]
S2[Iceberg] --> S2a["✅ 一等公民"]
S3[Delta] --> S3a["✅✅ 最佳"]
end
subgraph "Flink 支持"
F1[Hudi] --> F1a["✅✅ 最佳"]
F2[Iceberg] --> F2a["✅ 良好"]
F3[Delta] --> F3a["⚠️ 一般"]
end
subgraph "Trino/Presto"
T1[Hudi] --> T1a["✅ 良好"]
T2[Iceberg] --> T2a["✅✅ 最佳"]
T3[Delta] --> T3a["✅ 良好"]
end
| 引擎 | Hudi | Iceberg | Delta Lake |
|---|---|---|---|
| Spark | ✅ 良好 | ✅ 良好 | ✅✅ 最佳 |
| Flink | ✅✅ 最佳 | ✅ 良好 | ⚠️ 一般 |
| Trino/Presto | ✅ 良好 | ✅✅ 最佳 | ✅ 良好 |
| Hive | ✅ | ✅ | ✅ |
| Dremio | ✅ | ✅✅ | ✅ |
| Snowflake | ❌ | ✅ | ✅ |
五、写入性能对比
5.1 写入模式
graph TB
subgraph "Hudi 写入"
H1[COW: Copy-On-Write]
H2[MOR: Merge-On-Read]
H1 --> H1a["读优化,写放大"]
H2 --> H2a["写优化,读需合并"]
end
subgraph "Iceberg 写入"
I1[COW: 默认]
I2[MOR: v2 支持]
I1 --> I1a["Delete File"]
I2 --> I2a["Position/Equality Delete"]
end
subgraph "Delta 写入"
D1[仅 COW]
D1 --> D1a["Deletion Vectors (新)"]
end
5.2 Upsert 性能对比
xychart-beta
title "10亿行数据 Upsert 性能(相对值,越低越好)"
x-axis ["少量更新(1%)", "中量更新(10%)", "大量更新(50%)"]
y-axis "耗时(相对值)" 0 --> 100
bar [30, 45, 70]
bar [40, 50, 65]
bar [50, 60, 80]
| 场景 | Hudi | Iceberg | Delta Lake |
|---|---|---|---|
| 少量更新 (1%) | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 中量更新 (10%) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 大量更新 (50%) | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| 纯追加写入 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
关键差异:
- Hudi:内置索引,定位记录快,少量更新最优
- Iceberg:MOR 模式用 Delete File,中等更新友好
- Delta:COW 模式为主,纯追加最优
六、读取性能对比
6.1 查询优化能力
graph TB
subgraph "Hudi 查询优化"
H1[Bloom Filter]
H2[Data Skipping]
H3[Metadata Table]
end
subgraph "Iceberg 查询优化"
I1[Manifest 统计]
I2[列级 Min/Max]
I3[分区裁剪]
I4[谓词下推]
end
subgraph "Delta 查询优化"
D1[Data Skipping]
D2[Z-Order]
D3[Bloom Filter Index]
end
6.2 查询场景对比
| 查询场景 | Hudi | Iceberg | Delta Lake |
|---|---|---|---|
| 全表扫描 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 点查询 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| 范围查询 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 复杂聚合 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 增量读取 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
七、特色功能深度对比
7.1 增量处理能力
graph LR
subgraph "Hudi 增量查询"
H1["指定 beginTime/endTime"]
H2["返回变化的记录"]
H3["支持 CDC 格式输出"]
H4["增量 ETL 首选"]
end
graph LR
subgraph "Iceberg 增量查询"
I1["基于 Snapshot"]
I2["Incremental Read"]
I3["不如 Hudi 灵活"]
end
graph LR
subgraph "Delta 增量查询"
D1["CDF (Change Data Feed)"]
D2["需要开启功能"]
D3["支持 CDC 格式"]
end
增量查询代码对比:
// ===== Hudi 增量查询 =====
spark.read
.format("hudi")
.option("hoodie.datasource.query.type", "incremental")
.option("hoodie.datasource.read.begin.instanttime", "20240115100000")
.option("hoodie.datasource.read.end.instanttime", "20240115120000")
.load("/path/to/hudi_table")
// ===== Iceberg 增量查询 =====
spark.read
.format("iceberg")
.option("start-snapshot-id", "1234567890")
.option("end-snapshot-id", "1234567899")
.load("/path/to/iceberg_table")
// ===== Delta 增量查询 (CDF) =====
spark.read
.format("delta")
.option("readChangeFeed", "true")
.option("startingVersion", 5)
.option("endingVersion", 10)
.load("/path/to/delta_table")7.2 分区演进能力
graph TB
subgraph "Iceberg 分区演进"
I1["月分区 → 天分区"] --> I2["无需重写数据"]
I2 --> I3["查询自动处理"]
I3 --> I4["业界最强 ⭐⭐⭐⭐⭐"]
end
subgraph "Hudi 分区演进"
H1["支持分区变更"] --> H2["需要重写数据"]
H2 --> H3["功能相对弱"]
end
subgraph "Delta 分区演进"
D1["支持添加分区列"] --> D2["历史数据需重写"]
D2 --> D3["功能中等"]
end
7.3 Schema 演进能力
| 操作 | Hudi | Iceberg | Delta Lake |
|---|---|---|---|
| 添加列 | ✅ | ✅ 任意位置 | ✅ |
| 删除列 | ✅ | ✅ 软删除 | ✅ |
| 重命名列 | ⚠️ 有限 | ✅ | ✅ |
| 类型变更 | ⚠️ 有限 | ✅ 安全变更 | ⚠️ 有限 |
| 列重排序 | ❌ | ✅ | ❌ |
八、运维对比
8.1 表维护操作
graph TB
subgraph "Hudi 维护"
H1[Compaction]
H2[Clustering]
H3[Clean]
H4[Archive]
end
subgraph "Iceberg 维护"
I1[Expire Snapshots]
I2[Remove Orphan Files]
I3[Rewrite Data Files]
I4[Rewrite Manifests]
end
subgraph "Delta 维护"
D1[OPTIMIZE]
D2[VACUUM]
D3[Z-ORDER]
end
8.2 维护命令对比
-- ===== Hudi 维护 =====
-- Compaction (MOR 表)
CALL run_compaction(table => 'db.hudi_table', op => 'run');
-- Clustering
CALL run_clustering(table => 'db.hudi_table');
-- 清理
CALL run_clean(table => 'db.hudi_table');
-- ===== Iceberg 维护 =====
-- 过期快照
CALL system.expire_snapshots('db.iceberg_table', TIMESTAMP '2024-01-01', 100);
-- 清理孤儿文件
CALL system.remove_orphan_files('db.iceberg_table');
-- 重写小文件
CALL system.rewrite_data_files(table => 'db.iceberg_table');
-- ===== Delta 维护 =====
-- 优化(合并小文件)
OPTIMIZE delta.`/path/to/table`;
-- Z-Order 优化
OPTIMIZE delta.`/path/to/table` ZORDER BY (user_id);
-- 清理历史文件
VACUUM delta.`/path/to/table` RETAIN 168 HOURS;8.3 监控指标
| 监控项 | Hudi | Iceberg | Delta |
|---|---|---|---|
| 文件数量 | ✅ | ✅ | ✅ |
| 小文件数 | ✅ | ✅ | ✅ |
| Compaction 进度 | ✅ | ✅ | ✅ |
| 写入延迟 | ✅ | ✅ | ✅ |
| 快照数量 | ✅ | ✅ | ✅ |
| 内置监控 UI | ❌ | ❌ | ⚠️ Databricks |
九、云厂商支持
9.1 云服务集成
graph TB
subgraph "AWS"
AWS1[EMR] --> A1[Hudi ✅ Iceberg ✅ Delta ✅]
AWS2[Glue] --> A2[Hudi ✅ Iceberg ✅ Delta ✅]
AWS3[Athena] --> A3[Iceberg ✅✅]
end
subgraph "Azure"
AZ1[Synapse] --> B1[Delta ✅✅]
AZ2[Databricks] --> B2[Delta ✅✅✅]
end
subgraph "GCP"
GCP1[BigQuery] --> C1[Iceberg ✅]
GCP2[Dataproc] --> C2[All ✅]
end
9.2 云厂商偏好
| 云厂商 | 首选 | 说明 |
|---|---|---|
| AWS | Iceberg | Athena、Glue 深度集成 |
| Azure | Delta Lake | Databricks、Synapse 原生 |
| GCP | Iceberg | BigQuery 集成 |
| 阿里云 | Hudi | EMR 深度集成 |
| 国内云 | Hudi | 社区活跃,文档多 |
十、选型决策框架
10.1 决策流程图
flowchart TD
START[开始选型] --> Q1{核心场景?}
Q1 -->|CDC/实时更新| Q2{Flink 还是 Spark?}
Q1 -->|分析为主| Q3{多引擎访问?}
Q1 -->|Databricks 用户| A1[Delta Lake]
Q2 -->|Flink 为主| A2[Hudi]
Q2 -->|Spark 为主| Q4{更新频率?}
Q3 -->|是,多引擎| A3[Iceberg]
Q3 -->|Spark 为主| Q5{云厂商?}
Q4 -->|高频更新| A2
Q4 -->|中低频更新| Q5
Q5 -->|AWS| A3
Q5 -->|Azure| A1
Q5 -->|国内云| A2
style A1 fill:#ff6b6b
style A2 fill:#4ecdc4
style A3 fill:#ffeaa7
10.2 场景推荐表
| 场景 | 首选 | 次选 | 说明 |
|---|---|---|---|
| CDC 实时入湖 | Hudi | Delta | 增量处理最强 |
| 多引擎数据湖 | Iceberg | Hudi | 开放标准 |
| Databricks 环境 | Delta | - | 原生支持 |
| Flink 实时数仓 | Hudi | Iceberg | Flink 集成最好 |
| Spark 批处理 | Delta | Iceberg | Spark 原生优化 |
| 数据审计/合规 | Iceberg | Delta | 时间旅行完善 |
| Schema 频繁变更 | Iceberg | Delta | 演进能力最强 |
| 国内企业 | Hudi | Iceberg | 中文社区活跃 |
10.3 综合评分
radar
title 三大表格式综合能力
variables [增量处理, Schema演进, 多引擎支持, 社区生态, 易用性, 性能]
| 维度 | Hudi | Iceberg | Delta Lake |
|---|---|---|---|
| 增量处理 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Schema 演进 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 多引擎支持 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 社区生态 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 易用性 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 性能 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
十一、迁移指南
11.1 从 Hive 迁移
flowchart LR
A[Hive表] --> B{选择目标}
B --> C[Hudi]
B --> D[Iceberg]
B --> E[Delta]
C --> C1["Hudi提供迁移工具
支持原地转换"] D --> D1["Iceberg提供迁移程序
需要重写数据"] E --> E1["CONVERT TO DELTA
最简单"]
支持原地转换"] D --> D1["Iceberg提供迁移程序
需要重写数据"] E --> E1["CONVERT TO DELTA
最简单"]
-- Delta 从 Parquet 转换
CONVERT TO DELTA parquet.`/path/to/parquet_table`;
-- Iceberg 从 Hive 迁移
CALL system.migrate('hive_db.hive_table');
-- Hudi 迁移
-- 使用 HoodieTableMigrator 工具11.2 格式间迁移
graph LR
A[Hudi] -->|导出 Parquet| B[中转]
C[Iceberg] -->|导出 Parquet| B
D[Delta] -->|导出 Parquet| B
B --> A
B --> C
B --> D
十二、总结
12.1 一句话总结
graph LR
A[Hudi] --> A1["CDC和增量处理
选我!"] B[Iceberg] --> B1["开放标准和多引擎
选我!"] C[Delta Lake] --> C1["Databricks生态
选我!"]
选我!"] B[Iceberg] --> B1["开放标准和多引擎
选我!"] C[Delta Lake] --> C1["Databricks生态
选我!"]
Hudi:增量处理王者,CDC 场景首选,Flink 集成最好
Iceberg:开放标准之选,多引擎友好,Schema 演进最强
Delta Lake:Spark 生态最佳,Databricks 原生,上手最简单
12.2 最终建议
mindmap
root((选型建议))
选Hudi
CDC实时入湖
Flink技术栈
国内企业
高频更新场景
选Iceberg
多引擎访问
AWS云环境
Schema频繁变更
开放标准需求
选Delta
Databricks用户
Spark技术栈
Azure云环境
快速上手需求
12.3 趋势展望
timeline
title 数据湖表格式趋势
2024 : 三者功能趋同
2024 : UniForm 出现 (Delta 兼容 Iceberg)
2025 : 可能出现统一标准?
未来 : 竞争与融合并存
值得关注的趋势:
- Delta UniForm:Delta 可以被 Iceberg/Hudi 读取
- Iceberg REST Catalog:成为事实标准
- Hudi 0.15+:性能大幅提升
- 功能趋同:差异越来越小