1. 摘要
Apache Hudi除了支持insert和upsert外,還支持bulk_insert操作將數據攝入Hudi表,對於bulk_insert操作有不同的使用模式,本篇博客將闡述bulk_insert不同的模式以及與其他操作的比較。
Apache Hudi支持bulk_insert操作來將數據初始化至Hudi表中,該操作相比insert和upsert操作速度更快,效率更高。bulk_insert不會查看已存在數據的開銷並且不會進行小文件優化。
bulk_insert按照以下原則提供了3種模式來滿足不同的需求
•如果數據布局良好,排序將為我們提供良好的壓縮和upsert性能。特別是記錄鍵具有某種排序(時間戳等)特徵,則排序將有助於在upsert期間裁剪大量文件,如果數據是按頻繁查詢的列排序的,那麼查詢將利用parquet謂詞下推來裁剪數據,以確保更低的查詢延遲。•寫parquet文件是內存密集型操作。當將大量數據寫入一個也被劃分為1000個分區的表中時,如果不進行任何排序,寫入程序可能必須保持1000個parquet寫入器處於打開狀態,同時會產生不可持續的內存壓力,並最終導致崩潰。
•在批量導入數據時,最好控制好少的文件個數,以避免以後寫入和查詢時的元數據開銷。
3種開箱即用的模式為:PARTITION_SORT、GLOBAL_SORT、NONE
2. 配置
可以通過hoodie.bulkinsert.sort.mode[1]配置項來設置上述模式(NONE,GLOBAL_SORT,PARTITION_SORT),默認值為GLOBAL_SORT。
3. 不同模式3.1 GLOBAL_SORT(全局排序)
顧名思義,Hudi在輸入分區中對記錄進行全局排序,從而在索引查找過程中最大化使用鍵範圍修剪的文件數量,以便提升upsert性能。這是因為每個文件都具有非重疊的鍵的最小值和最大值,這在鍵具有某些排序特徵(例如基於時間的前綴)時非常有用。假設我們在任何給定的時間都在單個輸出分區路徑上寫入單個parquet文件,此模式在大分區寫入期間有助於控制內存壓力。同樣由於全局排序,每個小表分區路徑將從最多有兩個分區寫入,因此只包含2個文件。該模式是Hudi中進行bulk_insert操作的默認模式。
3.2 PARTITION_SORT(分區排序)
在這種排序模式下將對給定spark分區內的記錄進行排序,但是給定的spark分區可能包含來自不同表分區的記錄,因此即使我們在每個spark分區內進行排序,也可能會在產生大量文件,因為給定表分區的記錄可能會分布在許多spark分區中。在寫入器實際寫入時可能不會同時打開太多文件,因為我們在移動到下一個文件之前關閉了該文件(記錄在spark分區中排序),因此可能沒有太大的內存壓力。
3.3 NONE
在此模式下,不會對用戶記錄進行任何轉換(如排序),將數據原樣委託給寫入器。因此在將大量數據寫入分區為1000個分區的表中時,寫入程序可能必須保持1000個parquet寫入程序處於打開狀態,同時可能會產生較大內存壓力,有可能導致崩潰,因此該模式下會有較大的內存開銷。此外給定文件的最小-最大範圍可能非常寬(未排序的記錄),因此後續的upsert會在索引查找期間從大量文件中讀取bloom filter(布隆過濾器)。由於記錄沒有排序,並且每個寫入器可以跨N個表分區獲取記錄,因此這種模式可能會導致在bulk_insert結束時產生大量文件。由於有大量的小文件,這也可能會影響upsert或查詢性能。
4. 用戶自定義Partitioner
如果上述模式都不能滿足需求,用戶可以自定義實現partitioner[2]來滿足業務需求。
5. 性能測試
不同模式下簡單benchmark性能差異如下
說明:該基準測試使用不同的排序模式將1000萬條記錄批量插入hudi,然後upsert100W個條記錄(原始數據集大小的10%)。
顯而易見,NONE模式對批量導入性能最佳,因為它不涉及任何排序。與NONE模式相比,GLOBAL_SORT相比NONE模式開銷約為15%。PARTITION_SORT相比NONE模式開銷約為4%,因為也涉及到對記錄的排序操作。但是要注意的是後面的upsert性能。如前所述,與其他兩種排序模式相比全局排序具有許多優勢,GLOBAL_SORT相比NONEupsert性能高40%。PARTITION_SORT相比NONE模式有約5%的改進,這是由於大量小文件開銷導致。
6. 總結
希望這個博客能讓你很好地了解bulk_insert中的不同模式以及何時使用哪種模式。如果想參與Hudi社區,請點擊這裡[3]。
推薦閱讀
Flink + Hudi,構架倉湖一體化解決方案
基於Apache Hudi 的CDC數據入湖
內附PPT下載|萬字乾貨!阿里雲基於Apache Hudi構建Lakehouse實踐探索
一文徹底掌握Apache Hudi異步Clustering部署
使用 Flink Hudi 構建流式數據湖
引用鏈接
[1]hoodie.bulkinsert.sort.mode:https://hudi.apache.org/docs/configurations.html#withBulkInsertSortMode[2]partitioner:https://github.com/apache/hudi/blob/master/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/BulkInsertPartitioner.java[3]這裡:https://hudi.apache.org/contribute/get-involved