数据湖-Iceberg-源码学习-Kernal-Table-数据操作-Upsert
一、概述
Hudi 在处理 Upsert 请求时,会有一个 tagging 过程,主要是给每条数据打标,标明这条数据是 insert 还是 update。这个标签起到以下作用:
- 对于 insert 的数据,Hudi 会写入新的 base 文件
- 对于 update 的数据,Hudi 会写入新的 delta 文件,文件名使用原数据的 fileId
Hudi 为了快速地确定每条数据到底是 insert 还是 update,减少 tagging 的时间,还引入了索引机制。索引支持三种不同的类型,但每一种类型或多或少都会带来一些成本,或是影响写入性能,或是增加维护成本。
Iceberg 没有 tagging 过程,也无需外部中间件作为索引,但相应的,Iceberg 的 update 和 delete 并不确定想要更新或删除的记录是否存在,无论如何都会在 DeleteFile 里追加一条 delete 记录,至于这条记录是否真的存在,只有在读取时做合并后才知道。
本质上相当于把 tagging 的过程放在了读取阶段,尽管减少了写入时的成本,但会影响读取的效率。
二、实现
2.1. update
对于数据的 update,和 delete 同理,只不过 Iceberg 不仅在 DeleteFile 里写入一条记录删除旧数据,还会在 DataFile 里写入一条新数据的记录,相当于通过 “delete+insert” 来实现 update。
和 Hudi 的 mor 表基本思路类似,都是一种 “base+delta” 的方式
引用本站文章
数据湖-Iceberg-源码学习-API-Writer-update-设计
Joker
2.2. insert
Iceberg 数据写入流程:
- 先把数据写入到 data file 文件中
- 当一组 data file 文件写完之后,会根据这个 data file 文件中 column 的一些统计信息(如: 每个 column 的 min/max 值),生成一个对应的manifest文件
- 然后 Iceberg 把一次写入后涉及到的 manifest 文件组成一个 manifest list,manifest list 文件中也会存入一些相关 manifest 的统计信息(如:分区信息,manifest 有效性)等
- 然后按照整个 manifest list 生成一个对应的 snapshot 文件
- 生成完 snapshot 文件之后,Iceberg 会把当前 snapshot 的 ID 及存储路径等信息写入到 metadata 文件中
- 当一切准备完毕之后,会以原子操作的方式 commit 这个 metadata 文件,这样一次 Iceberg 的数据写入就完成了。随着每次的写入 Iceberg 就生成了如这样的一个文件组织模式。
三、总结
和 Hudi 有所不同,Hudi 通过 Index 的索引机制,在写入时实时判断索引来达到 Upsert 的功能,而 Iceberg 则是通过良好的文件组织形式,在读取时做合并 MOR(Merge-on-Read)的思路,所以 Hudi 对读取友好,而 Iceberg 对写入友好。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Joker!
评论
ValineTwikoo











