Hudi 原理 - Apache Hudi 如何處理小文件問題
1. 引入
Apache Hudi 是一個流行的開源的數據湖框架,Hudi 提供的一個非常重要的特性是自動管理文件大小,而不用用戶干預。大量的小文件將會導致很差的查詢分析性能,因爲查詢引擎執行查詢時需要進行太多次文件的打開 / 讀取 / 關閉。在流式場景中不斷攝取數據,如果不進行處理,會產生很多小文件。
2. 寫入時 vs 寫入後
一種常見的處理方法先寫入很多小文件,然後再合併成大文件以解決由小文件引起的系統擴展性問題,但由於暴露太多小文件可能導致不能保證查詢的 SLA。實際上對於 Hudi 表,通過 Hudi 提供的 Clustering 功能可以非常輕鬆的做到這一點,更多細節可參考之前一篇文章查詢時間降低 60%!Apache Hudi 數據佈局黑科技瞭解下。
本篇文章將介紹 Hudi 的文件大小優化策略,即在寫入時處理。Hudi 會自管理文件大小,避免向查詢引擎暴露小文件,其中自動處理文件大小起很大作用。
在進行insert/upsert
操作時,Hudi 可以將文件大小維護在一個指定文件大小(注意:bulk_insert 操作暫無此特性,其主要用於替換spark.write.parquet
方式將數據快速寫入 Hudi)。
3. 配置
我們使用 COPY_ON_WRITE 表來演示 Hudi 如何自動處理文件大小特性。
關鍵配置項如下:
•hoodie.parquet.max.file.size[1]:數據文件最大大小,Hudi 將試着維護文件大小到該指定值;•hoodie.parquet.small.file.limit[2]:小於該大小的文件均被視爲小文件;•hoodie.copyonwrite.insert.split.size[3]:單文件中插入記錄條數,此值應與單個文件中的記錄數匹配(可以根據最大文件大小和每個記錄大小來確定)
例如如果你第一個配置值設置爲 120MB,第二個配置值設置爲 100MB,則任何大小小於 100MB 的文件都將被視爲一個小文件,如果要關閉此功能,可將hoodie.parquet.small.file.limit
配置值設置爲 0。
4. 示例
假設一個指定分區下數據文件佈局如下
假設配置的hoodie.parquet.max.file.size
爲 120MB,hoodie.parquet.small.file.limit
爲 100MB。File_1 大小爲 40MB,File_2 大小爲 80MB,File_3 是 90MB,File_4 是 130MB,File_5 是 105MB,當有新寫入時其流程如下:
**步驟一:**將更新分配到指定文件,這一步將查找索引來找到相應的文件,假設更新會增加文件的大小,會導致文件變大。當更新減小文件大小時(例如使許多字段無效),則隨後的寫入將文件將越來越小。
**步驟二:**根據hoodie.parquet.small.file.limit
決定每個分區下的小文件,我們的示例中該配置爲 100MB,所以小文件爲 File_1、File_2 和 File_3;
**步驟三:**確定小文件後,新插入的記錄將分配給小文件以便使其達到 120MB,File_1 將會插入 80MB 大小的記錄數,File_2 將會插入 40MB 大小的記錄數,File_3 將插入 30MB 大小的記錄數。
**步驟四:**當所有小文件都分配完了對應插入記錄數後,如果還有剩餘未分配的插入記錄,這些記錄將分配給新創建的 FileGroup / 數據文件。數據文件中的記錄數由hoodie.copyonwrite.insert.split.size
(或者由之前的寫入自動推算每條記錄大小,然後根據配置的最大文件大小計算出來可以插入的記錄數)決定,假設最後得到的該值爲 120K(每條記錄大小 1K),如果還剩餘 300K 的記錄數,將會創建 3 個新文件(File_6,File_7,File_8),File_6 和 File_7 都會分配 120K 的記錄數,File_8 會分配 60K 的記錄數,共計 60MB,後面再寫入時,File_8 會被認爲小文件,可以插入更多數據。
Hudi 利用諸如自定義分區之類的機制來優化記錄分配到不同文件的能力,從而執行上述算法。在這輪寫入完成之後,除 File_8 以外的所有文件均已調整爲最佳大小,每次寫入都會遵循此過程,以確保 Hudi 表中沒有小文件。
5. 總結
本文介紹了 Apache Hudi 如何智能地管理小文件問題,即在寫入時找出小文件並分配指定大小的記錄數來規避小文件問題,基於該設計,用戶再也不用擔心 Apache Hudi 數據湖中的小文件問題了。
引用鏈接
[1]
hoodie.parquet.max.file.size: http://hudi.apache.org/docs/configurations.html#limitFileSize
[2]
hoodie.parquet.small.file.limit: (http://hudi.apache.org/docs/configurations.html#compactionSmallFileSize)
[3]
hoodie.copyonwrite.insert.split.size: http://hudi.apache.org/docs/configurations.html#insertSplitSize
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/6OevkOuPL0NAL--YaU2Avg