首页/数据/数仓建模速查/Iceberg 小文件合并与重写
湖仓与引擎63 条

Iceberg 小文件合并与重写

用小文件重写动作合并数据文件、按目标大小重组;顺带可以重排清单文件降低元数据开销,建议按分区调度而非整表。

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

合并解决哪两个问题

写入频繁的表会积累大量小文件,读取时要打开成百上千个文件,元数据清单也跟着膨胀。合并动作把同一批小文件按目标大小重组成大文件,顺带重写清单文件,让规划阶段少读一些元数据。它不改数据内容,改的是文件布局。

基本信息

主要动作rewrite_data_files 重写数据文件
附带动作rewrite_manifests 重排清单文件
目标文件大小常见取 128MB 到 256MB
执行范围按分区或按查询热度挑选
执行窗口低峰期,避开写入高峰

典型使用场景

  • 流式落表:每天产生大量小文件,需要定期合并成目标大小
  • 历史分区整理:对访问频繁的分区优先处理
  • 查询规划变慢:manifest 过多时配合清单重写
  • 批量导入之后:导入产生的小文件在空闲时段统一整理
  • 容量优化:合并后压缩率通常更好,磁盘占用同步下降

Spark 过程调用示例

Spark 过程调用示例
-- 重写数据文件:合并小文件到目标大小
CALL demo.system.rewrite_data_files(
  table => 'db.trade_order',
  options => map('target-file-size-bytes', '134217728')  -- 128MB
);

-- 重排清单文件:降低元数据解析开销
CALL demo.system.rewrite_manifests(table => 'db.trade_order');

-- 清理孤立文件:窗口要足够长,避免误删提交中的文件
CALL demo.system.remove_orphan_files(
  table => 'db.trade_order',
  older_than => TIMESTAMP '2026-10-11 00:00:00'
);

维护动作对照

动作作用执行建议
rewrite_data_files合并小文件、按大小重组按分区调度,优先热点分区
rewrite_manifests重排清单文件与数据重写配套执行
expire_snapshots清理过期快照保留足够回溯期后再清理
remove_orphan_files删除无主文件时间窗充足,避免误删
整表重写不推荐作为常规手段成本高、耗时长

调度策略怎么定

合并任务最忌讳与写入任务抢资源,也不宜每天全量重写整表。可行做法是按分区维护一张热度表,把最近被查询最多的分区排在最前面,每天只处理固定数量的分区,落在写入低峰时段。这样单次任务的资源消耗可预期,出了问题也容易回退。

孤立文件清理的判定依据是文件是否被任何快照引用且超过指定时间;窗口设得太短,正在提交过程中的临时文件会被误删,导致表出现读取失败。
整表合并任务每月全量跑一次,耗时与资源消耗都难以预估,一旦超时中断还会留下一批半成品文件;按分区增量处理是更稳的选择。

易错点

  • 整表合并每月全量执行,耗时不可控且中途失败留下半成品
  • 孤立文件清理窗口设置过短,删掉写入中的临时文件导致表读取失败
  • 合并任务与写入任务并行,资源竞争下两边都变慢
  • 只做数据合并不清理旧快照,元数据体积仍在增长

数据来源与参考

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