本文为您介绍下火山引擎 E-MapReduce(EMR)集群中的 Hudi 组件。
Hudi 是一个流式数据湖平台,提供 ACID 功能,支持实时消费增量数据、离线批量更新数据,并且可以通过 Spark、Flink、Presto 等计算引擎进行查询。
相较于传统数仓,Hudi 要求每条记录必须有唯一的主键,并且同分区内,相同主键只存在在一个 file group 中,以此支持Update功能。目前 Hudi 主要存在以下两种表类型。
COW 表适用于离线批量更新场景,对于更新数据,会先读取旧的 base file,然后合并更新数据,生成新的 base file。
MOR 表适用于实时高频更新场景,更新数据会直接写入 log file 中,读时再进行合并。为了减少读放大的问题,会定期合并 log file 到 base file 中。File group 内的文件分为 base file 和 log file, log file 记录对 base file 的修改,通过 compaction 合并成新的 base file,多个版本的 base file 会同时存在。
对于数据集的所有操作,以 timeline 的形式描述。
Timeline 由一个个 commit 构成,一次写入过程对应时间线中的一个 commit,记录本次写入修改的文件。在 basepath 的元数据目录下存储。对数据集的操作包括:
Commits:针对数据集的一次批量写入(原子)的信息,由写入操作开始的时间戳来唯一(单调)标记
Cleans:后台操作,删除对于查询无用的文件版本
Compactions:后台操作,对齐数据集在 Hudi 内部的不同格式(即,将行式的更新日志应用到列式存储中,合并成新的 base file)
将新进的 record key 映射到一个 File ID。索引是独立模块(可插拔),目前 EMR Hudi 主要提供以下索引:
Bloom 过滤器索引:包含在数据文件的 footer 中,默认配置,不依赖外部系统,数据和索引保持一致性。
HBase 索引:对于小批次的 keys,查询效率高。在索引命中的时候可能有秒级开销,需要引入额外 Hbase 依赖。
Hudi Bucket Index: EMR 1.2 Hudi 版本还率先引入了 Hudi Bucket Index 供选择, Bucket Index 一种基于哈希的索引,使得在插入过程中,定位传入 Record 的待写入文件位置信息时,无需读历史的 Record ,详细设计可以参考 RFC-29。
两种存储格式。具体的实现是可插拔的。两种格式的需求是:
ROFormat:针对 scan 操作优化,列存。默认配置是 Parquet。
WOFormat:针对写入优化,行存。默认配置是 Avro。