3、表格式规范详解:Iceberg v1 vs v2规范,列式存储与行级删除的核心区别
聊到Iceberg的表格式规范,很多初学者容易把v1和v2当成两个完全不同的东西。其实没那么复杂。我个人习惯把v1看作「基础版」,v2则是「增强版」。它们共享同一套列式存储骨架,但在行级删除和元数据管理上,v2做了关键升级。
今天我们就掰开揉碎,看看这两个版本到底差在哪。
3.1 列式存储:v1和v2的共享基石
先说共同点。无论是v1还是v2,底层数据文件都采用列式存储格式——Parquet、ORC或Avro。列式存储的好处,说白了就是按需读取。你想想看,一个表有100列,但查询只用到3列,行式存储得把整行数据都扫一遍,列式存储只读那3列的数据块,I/O开销直接降一个量级。
我在项目中遇到过这样一个场景:某张用户行为表有80多列,业务方每天跑聚合查询只取5个字段。改用Iceberg + Parquet后,查询耗时从分钟级降到秒级。嗯,这就是列式存储的威力。
核心要点:Iceberg v1和v2在数据文件层面完全兼容。v2新增的功能不会改变底层列式存储的物理格式,只是在上层元数据中增加了新的文件类型和操作语义。
3.2 v1规范:简单够用,但有硬伤
v1规范是Iceberg的初始版本,设计目标很明确——解决Hive表格式的痛点。它提供了快照隔离、分区演进和隐藏分区这些核心能力。
但v1有个明显的短板:不支持行级删除。这意味着什么?
- 如果你要更新或删除某几行数据,v1只能重写整个数据文件
- 对于频繁的小范围更新,会产生大量小文件
- Merge-on-read场景下,性能会急剧下降
我曾经帮一个金融客户排查数据管道延迟问题。他们的风控表每天有上千万条记录,但只更新其中几千条。用v1规范时,每次更新都要重写整个Parquet文件,数据文件从几十个膨胀到上千个。嗯,这就是典型的「小文件灾难」。
3.3 v2规范:行级删除的救星
v2规范的核心改进,就是引入了删除文件(Delete Files)的概念。它把更新和删除操作从「重写数据文件」变成了「追加删除记录」。
具体来说,v2支持两种删除文件:
| 删除文件类型 | 描述 | 适用场景 |
|---|---|---|
| Position Delete | 按文件路径 + 行号标记删除 | 精确删除,性能最优 |
| Equality Delete | 按字段值匹配删除 | 按业务主键删除,灵活性高 |
这两种删除文件,本质上都是小型的列式文件,记录哪些数据行「被标记为已删除」。查询时,Iceberg会合并数据文件和删除文件,过滤掉已删除的行。
我的建议:如果业务场景以批量覆盖为主(比如每天全量同步),v1完全够用。但如果涉及频繁的CDC流式更新或单行修正,直接上v2,别犹豫。我曾经在流式入湖项目中用v2,删除文件的体积通常只有数据文件的1%~5%,性能提升非常明显。
3.4 核心区别对比:一张表说清楚
我把v1和v2的关键差异整理成了一张表,方便你对照:
| 对比维度 | v1规范 | v2规范 |
|---|---|---|
| 行级删除 | 不支持,需重写数据文件 | 支持,通过删除文件实现 |
| 数据文件格式 | Parquet / ORC / Avro | 同上 + 删除文件(列式) |
| 快照隔离 | 支持 | 支持(增强) |
| 分区演进 | 支持 | 支持 |
| Merge-on-read | 性能差(全量重写) | 性能优(增量删除) |
| 元数据版本 | v1元数据格式 | v2元数据格式(新增删除文件清单) |
| 兼容性 | 所有Iceberg引擎支持 | 需要引擎支持v2(Spark 3.x+、Flink 1.14+) |
3.5 行级删除的底层原理
这里我展开讲讲v2的行级删除到底怎么工作的。你可能会问:「删除文件不会让查询变慢吗?」
答案是:会,但可控。
查询时,Iceberg的流程是这样的:
- 读取快照中的Manifest列表,找到所有数据文件和删除文件
- 对每个数据文件,检查是否有对应的删除文件
- 如果有,读取删除文件中的行号或键值
- 在读取数据文件时,跳过被标记删除的行
这个过程中,删除文件通常很小(只记录被删除的行),所以额外I/O开销有限。但如果删除文件积累太多,查询时合并的开销就会上升。这时候就需要做压缩(Compaction)——把数据文件和删除文件合并,生成新的数据文件,清理掉旧的删除文件。
避坑指南:我曾经在一个实时写入的场景中,忘记配置自动压缩策略。结果删除文件越积越多,查询延迟从200ms飙升到5秒。后来我设置了每1小时或每100个删除文件触发一次压缩,才把性能稳住。记住:行级删除不是银弹,配套的压缩策略必须跟上。
3.6 知识体系总览
下面这张SVG图,把v1和v2的差异、行级删除的流程、以及压缩的关系串起来了:
3.7 选型建议
最后,结合我自己的经验,给你几个选型建议:
- 新项目直接上v2:现在主流引擎(Spark 3.2+、Flink 1.14+、Trino)都支持v2,没必要走回头路
- 存量v1表迁移要谨慎:v2不向下兼容v1的元数据格式,迁移需要重写元数据。我建议先在小表上验证,再逐步推广
- 关注删除文件的膨胀速度:如果业务以插入为主、极少更新,v2的优势不明显,v1反而更简单