一. Hudi數據寫流程概述
在Hudi數據湖框架中支持三種方式寫入數據:UPSERT
(插入更新)、INSERT
(插入)和BULK INSERT
(批量寫入)
UPSERT
:默認行爲,數據先通過 index 打標
(INSERT/UPDATE),有一些啓發式算法決定消息的組織以優化文件的大小INSERT
:跳過 index,寫入效率更高BULK_INSERT
:寫排序,對大數據量的 Hudi 表初始化友好,對文件大小的限制 best effort(寫 HFile)
二. upsert寫流程
2.1 Copy On Write類型表,UPSERT 寫入流程
先對 records 按照 record key 去重;
首先對這批數據創建索引 (HoodieKey => HoodieRecordLocation);通過索引區分哪些 records 是 update,哪些 records 是 insert(key 第一次寫入);
對於 update 消息,會直接找到對應 key 所在的最新 FileSlice 的 base 文件,並做 merge 後寫新的 base file (新的 FileSlice);
對於 insert 消息,會掃描當前 partition 的所有 SmallFile(小於一定大小的 base file),然後 merge 寫新的 FileSlice;如果沒有 SmallFile,直接寫新的 FileGroup + FileSlice;
2.2 Merge On Read類型表,UPSERT 寫入流程
先對 records 按照 record key 去重(可選)
首先對這批數據創建索引 (HoodieKey => HoodieRecordLocation);通過索引區分哪些 records 是 update,哪些 records 是 insert(key 第一次寫入)
如果是 insert 消息,如果 log file 不可建索引(默認),會嘗試 merge 分區內最小的 base file (不包含 log file 的 FileSlice),生成新的 FileSlice;如果沒有 base file 就新寫一個 FileGroup + FileSlice + base file;如果 log file 可建索引,嘗試 append 小的 log file,如果沒有就新寫一個 FileGroup + FileSlice + base file
如果是 update 消息,寫對應的 file group + file slice,直接 append 最新的 log file(如果碰巧是當前最小的小文件,會 merge base file,生成新的 file slice)log file 大小達到閾值會 roll over 一個新的
三. insert寫流程
3.1 Copy On Write類型表,INSERT 寫入流程:
- 先對 records 按照 record key 去重(可選);
- 不會創建 Index;
- 如果有小的 base file 文件,merge base file,生成新的 FileSlice + base file,否則直接寫新的 FileSlice + base file;
3.2 Merge On Read類型表,INSERT 寫入流程
- 先對 records 按照 record key 去重(可選);
- 不會創建 Index;
- 如果 log file 可索引,並且有小的 FileSlice,嘗試追加或寫最新的 log file;如果 log file 不可索引,寫一個新的 FileSlice + base file;