Iceberg 是什么
Iceberg 是数据湖表格式,解决的是「对象存储上的一堆文件如何当成一张表来管理」:它用元数据文件记录快照、清单与分区信息,从而提供 ACID 提交、快照隔离、隐藏分区与模式演进。存储层可以是 HDFS 或对象存储,计算引擎(Spark、Flink、Trino 等)通过 Catalog 找到表并读写,同一份数据能被多个引擎共享。
基本信息
| 定位 | 数据湖表格式,管理文件与元数据 |
|---|---|
| 核心能力 | ACID 提交、快照隔离、模式演进、隐藏分区 |
| 存储层 | HDFS、S3、OSS 等对象存储 |
| 计算引擎 | Spark、Flink、Trino、Hive 等 |
| 访问方式 | Catalog + 表标识(库.表) |
典型使用场景
- 在对象存储上做数仓:对象存储没有原子重命名,靠 Iceberg 保证提交原子性
- 时间旅行:查询某个快照或某个时间点的数据,用于回滚与问题复现
- 多引擎共享数据:实时写入用 Flink,离线加工用 Spark,分析用 Trino
- 模式演进:新增、重命名、删除列不需要重写已有数据文件
- 分区演进:从按月分区改为按天分区时,历史数据不必重写
Spark 建表
Spark 建表
CREATE TABLE demo.db.trade_order (
order_id STRING,
store_id STRING,
pay_amt DECIMAL(18,2),
dt DATE
) USING iceberg
PARTITIONED BY (dt); -- 分区由表元数据记录,不靠目录名表达
INSERT INTO demo.db.trade_order VALUES ('O1','S1',100.00, DATE '2026-10-13');
-- 时间旅行:读取指定快照,用于复现问题或回滚
SELECT * FROM demo.db.trade_order VERSION AS OF 1234567890;核心能力
| 能力 | 说明 | 收益 |
|---|---|---|
| ACID 提交 | 提交以元数据替换的方式原子完成 | 读者只会看到完整的旧快照或新快照 |
| 快照与时间旅行 | 每次提交生成新快照,旧快照可查 | 便于数据回滚与问题复现 |
| 隐藏分区 | 分区由元数据推导,不体现在目录结构上 | 写入不会漏分区,查询无需知道分区列 |
| 模式演进 | 增删改列不重写已有数据文件 | 表结构变更成本低,适配上游频繁调整 |
Iceberg 的提交是原子性的:读到的要么是旧快照,要么是新快照,不会读到写了一半的结果。这也是它和「直接往目录里写文件」最本质的差别。
小文件治理在湖表上同样重要:每次写入都会生成新文件,实时写入场景会快速积累大量小文件,需要定期做小文件合并,否则查询规划时间会显著变长。