首页/数据/数仓建模速查/Apache Iceberg:表格式与快照管理
湖仓与引擎63 条

Apache Iceberg:表格式与快照管理

Iceberg 是数据湖表格式:提供 ACID 提交、快照隔离、隐藏分区与模式演进;存储层可以是 HDFS 或对象存储,计算引擎通过 Catalog 访问。

数仓建模速查数据更新于 2026-10-13

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 的提交是原子性的:读到的要么是旧快照,要么是新快照,不会读到写了一半的结果。这也是它和「直接往目录里写文件」最本质的差别。
小文件治理在湖表上同样重要:每次写入都会生成新文件,实时写入场景会快速积累大量小文件,需要定期做小文件合并,否则查询规划时间会显著变长。

易错点

  • 直接删目录里的数据文件:快照元数据与实际文件不一致,表会读不出来
  • 不做过期快照与孤儿文件清理:元数据与存储持续膨胀,查询规划变慢
  • 不做小文件合并:实时写入积累大量小文件,查询扫描开销成倍上升
  • 多引擎并发写同一张表且不做并发控制:提交冲突导致作业反复失败
  • 把湖表当普通目录长期堆放文件:单表文件数上万后,规划时间远超实际扫描时间

数据来源与参考

  • Apache Iceberg 官方文档:Introduction
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌