首页/数据/数据工程与 ETL 速查/Apache Iceberg 基础用法
管道基础52 条

Apache Iceberg 基础用法

Iceberg 是开放表格式:用元数据文件管理快照与清单,支持隐藏分区、schema 演进与快照级时间旅行;Spark/Flink/Trino 等多引擎可读写同一张表。

Iceberg 是什么

Apache Iceberg 是一种开放表格式:它在对象存储或 HDFS 之上用元数据文件描述「这张表当前由哪些数据文件组成」,把文件组织、分区信息与统计信息集中管理。数据文件本身仍是 Parquet 等通用格式,因此同一张表可以被 Spark、Flink、Trino 等多个引擎同时读写。

快照是怎么工作的

每次写入都会生成一个新的快照与清单文件,指向本次提交后的数据文件集合,而不会就地修改旧文件。这种「先写新文件、再原子提交元数据」的方式让写入具备原子性,也顺带带来了时间旅行与快照回滚能力:查询可以指定某个快照或时间点。

基本信息

定位开放表格式,管理元数据与数据文件的关系
核心机制快照加清单文件描述表状态,写入先提交新快照
关键能力隐藏分区、时间旅行、schema 演进、增量读
引擎兼容Spark、Flink、Trino、Hive 等可读写同一张表
日常维护快照过期、清单合并、小文件重写

元数据表读法

元数据表内容用途
table.snapshots所有快照及其时间戳定位可回滚的快照编号
table.history提交历史与快照演进追查某次变更发生在什么时间
table.files当前快照包含的数据文件统计文件数量与大小,判断小文件问题
table.manifests清单文件列表分析元数据规模与规划耗时

典型使用场景

  • 数据湖明细层:需要行级 upsert 与 schema 演进,而 Parquet 目录无法胜任
  • 多引擎共用一份数据:批用 Spark、流用 Flink、即席查询用 Trino
  • 口径回滚:发现加工逻辑有误时按快照回滚到出问题之前的状态
  • 增量读取:只消费两次快照之间新增的数据文件
  • 审计与复现:按时间点查询历史状态,复现当时的报表结果

Spark SQL 使用 Iceberg

Spark SQL 使用 Iceberg
-- 按天分区(隐藏分区:查询直接按 ts 过滤即可命中,无需感知分区函数)
CREATE TABLE local.db.orders (
  order_id STRING, amount DOUBLE, ts TIMESTAMP
) USING iceberg PARTITIONED BY (days(ts));

INSERT INTO local.db.orders VALUES ('o1', 9.9, TIMESTAMP '2026-10-11 10:00:00');

-- 元数据表:看快照与提交历史
SELECT * FROM local.db.orders.snapshots;
SELECT * FROM local.db.orders.history;

-- 时间旅行:按快照编号或时间点查询历史状态
SELECT * FROM local.db.orders VERSION AS OF 1234567890;
SELECT * FROM local.db.orders TIMESTAMP AS OF '2026-10-11 00:00:00';

日常维护过程调用

日常维护过程调用
-- 回滚到某个快照(写错数据后的应急手段)
CALL local.system.rollback_to_snapshot('db.orders', 1234567890);

-- 小文件合并:把大量小文件重写成合适大小的文件
CALL local.system.rewrite_data_files(table => 'db.orders');

-- 快照过期:清理过期快照与孤立文件,避免元数据持续膨胀
CALL local.system.expire_snapshots(table => 'db.orders', older_than => TIMESTAMP '2026-10-01 00:00:00');
CALL local.system.remove_orphan_files(table => 'db.orders');
隐藏分区的价值在于把分区细节从查询里去掉:表按 days(ts) 分区,查询直接写 WHERE ts >= ... 就能命中,不必再维护「分区列必须裸用」的书写纪律。
快照与清单不做过期清理,元数据会持续膨胀:表现为查询规划时间越来越长、文件打开开销越来越大,通常需要按保留策略定期执行过期与重写。

易错点

  • 快照与清单长期不清理,元数据持续膨胀,查询规划耗时逐步上升
  • 小文件不重写,写入频率越高文件越多,扫描性能随之劣化
  • 直接删除底层数据文件而不通过表接口,快照引用的文件缺失导致查询直接报错
  • 误以为时间旅行能一直回溯:快照过期后旧版本不再可用,保留窗口需要显式规划

数据来源与参考

  • Apache Iceberg 官方文档:Spark Quickstart 与 Maintenance
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌