Copy On Write
在COW表中,只有数据文件/基本文件(.parquet),没有增量日志文件(.log.*)
对每一个新批次写入都将创建相应数据文件的新版本(新的FileSlice),新版本文件包括旧版本文件的记录以及来自传入批次的记录(全量最新)。
假设我们有3个文件组,其中包含如下数据文件。
我们进行一批新的写入,在索引后,我们发现这些记录与File group 1 和File group 2匹配,然后就有新的插入,我们为其创建一个新的文件组(File group 4)
因此 data_file1和data_file2都将创建更新的版本,data_file V2是data_file V1的内容与data_file1中传入批次匹配记录的记录合并
由于在写入期间进行合并,COW会产生一些写入延迟。但是COW的优势在于它的简单性,不需要其他表服务(如压缩),也相对容易调试。
Merge On Read
MOR表中,包含列存的基本文件(.parquet)和行存的增量日志文件(基于行的avro格式,.log.*)。
顾名思义,MOR表的合并成本在读取端。因此在写入期间我们不会合并或创建较新的数据文件版本。标记/索引完成后,对于具有要更新记录的现有数据文件,Hudi创建增量日志文件并适当命名它们,以便它们都属于一个文件组。
读取端将实时合并基本文件及其各自的增量日志文件。每次的读取延迟都比较高(因为查询时进行合并),所以Hudi使用压缩机制来将数据文件和日志文件合并在一起并创建更新版本的数据文件;
用户可以选择内联或异步模式进行压缩。Hudi也提供了不同的压缩策略供用户选择,最常用的一种是基于提交的数量。例如可以将压缩的最大增量日志配置为4.这就意味着在进行4次增量写入后,将对数据文件进行压缩并创建更新版本的数据文件。压缩完成后,读取端只需要读取最新的数据文件,而不必关心旧版本文件。
MOR表的写入行为,依据index的不同会有细微的差别;
对于BloomFilter这种无法对log file 生成index的索引方案,对于INSERT消息仍然会写base file (parquet format),只有update消息会append log 文件(因为 base log已经记录了该update 消息的FileGroup ID);
对于可以对logfile生成index的索引方案,例如Flink writer 中基于state的索引,每次写入都是log format,并且会不断增加和rool over;