Apache Hudi 是一款開源的[數據湖解決方案](https://www.dtstack.com/dtengine/easylake?src=szsm),它能夠幫助企業更好地管理和分析海量數據,支持高效的[數據更新和查詢](https://www.dtstack.com/dtengine/ea ...
Apache Hudi 是一款開源的數據湖解決方案,它能夠幫助企業更好地管理和分析海量數據,支持高效的數據更新和查詢。並提供多種數據壓縮和存儲格式以及索引功能,從而為企業數據倉庫實踐提供更加靈活和高效的數據處理方式。
在金融領域,企業可以使用 Hudi 來處理大量需要實時查詢和更新的金融交易數據。在電商業務中,企業可以使用 Hudi 來跟蹤訂單數據,以及對訂單進行實時更新和查詢。在物流和供應鏈管理中,Hudi 可以幫助企業實時處理和更新大量的物流數據,保證數據的一致性和可靠性。
作為一站式大數據基礎軟體的袋鼠雲數棧,基於 Apache Hudi 為客戶提供了存量數據遷移、數據入湖、文件治理等完整支持能力。在這個過程中,積累了一些 Hudi 性能優化的經驗,希望通過本文與大家分享交流。
Hudi 原理簡析
Apache Hudi 是一個開源的數據湖解決方案,它是基於 Hadoop 和 Spark 的技術棧構建而成,並且拓展到了 Flink、 Trino 等多種計算引擎。Apache Hudi 的主要目的是提供一個高效、可擴展且可靠的數據湖解決方案,用於管理和處理大規模的數據集。
Hudi 的核心實現是通過將數據集合劃分為多個數據文件,併為每個數據文件維護一個數據版本和索引信息,來支持增量數據更新和查詢操作。如下圖所示,當用戶需要對數據進行更新時,Hudi 會將更新的數據寫入一個新的數據文件中,並通過寫時複製(copy-on-write)操作,將原始數據文件中的數據記錄複製到新的數據文件中,併在新的數據文件中更新對應的數據記錄。
同時,Hudi 會更新數據版本和索引信息,以便用戶可以根據數據版本和唯一標識符來訪問最新的數據記錄。當用戶需要查詢數據時,Hudi 會使用索引信息來定位數據記錄,並返回最新的數據記錄。
在 Hudi 的 merge on read 模式中,更新操作是通過在查詢時將原始數據和更新數據進行合併來實現的。具體來說,當有新的數據要被寫入時,Hudi 會將新數據追加寫入到一個新的日誌文件中,併在元數據文件中記錄新文件的信息。當查詢數據時,Hudi 會將所有數據文件進行合併,生成一個視圖,然後對視圖進行查詢。
由於 Hudi 只需要在查詢時將需要更新的數據進行合併,而不需要在寫入時進行合併,因此可以避免寫入時的性能開銷,從而實現快速的更新操作。
Apache Hudi 在寫入數據時創建一個新版本,而讀取數據時通過將所有版本的數據進行合併來生成一個視圖。在視圖中,每個數據記錄只出現一次,並且是最新的版本,這樣可以保證讀操作只會涉及到視圖中的數據,而不會對原始數據進行修改,從而實現了讀寫分離。
通過多版本實現併發控制,Hudi 可以在保證數據一致性的前提下,提高讀操作的性能,同時也保證了數據的可靠性和可擴展性。
Hudi 優化實踐
下麵介紹基於袋鼠雲數棧的實踐經驗,所做的 Hudi 性能優化。
支持多索引
Hudi 將數據集合劃分為多個數據文件,併為每個數據文件維護一個數據版本和索引信息,來支持增量數據更新和查詢操作。通過構建索引就可以利用生成的元數據快速定位查詢所需數據的位置,如下圖所示。這樣可以減少甚至避免從文件系統中掃描或者讀取不必要的數據,減少 IO 的開銷,大大提升查詢效率。Hudi 已經支持幾種不同的索引技術,並且還在不斷地改進和添加更多的索引實現。
袋鼠雲數棧支持用戶在創建 Hudi 表時就設置想要使用的索引類型,包括 SIMPLE、BLOOM FILTER、BUCKET 等類型。在寫入過程中,Hudi 會將索引信息寫入到 parquet 文件或者外部存儲中,在讀取時應用程式根據這些信息進行比較判斷,跳過不必要的數據文件。
Hudi 在0.11.0版本引入了 MetadataTable 這種多模式索引,利用 MetadataTable 彙總元數據信息,應用程式可以避免文件系統調用文件 Listing 操作(這在對象存儲中是非常耗時的),還可以避免直接讀取 parquet 文件中的 footer 信息,能夠大幅提升查詢性能。
袋鼠雲數棧支持用戶在建表時就開啟多模式索引,在寫入數據的同時將文件的索引信息也寫入 MetadataTable。數棧還支持以非同步的方式構建 MetadataTable,保證寫入仍然處於低延遲的狀態,再由後臺的應用程式離線生成 MetadataTable 以提升讀取性能。
由於 MetadataTable 依賴 base 文件記錄的 column stats/bloomfilter 等信息,因此 merge on read 模式下沒有辦法將 log 文件的信息保存到 MetadataTable 中,開源框架上沒有利用它實現進行文件過濾。
但考慮到 base 文件和 log 文件共用相同的 fileId,袋鼠雲技術團隊在數棧內部進行了改造:通過 MetadataTable 獲取到 base 文件之後,再根據 fileId 進行 log 文件過濾,避免不必要讀取。經過驗證,這種改動能夠使得 merge on read 模式具備和 copy on write 模式相同的過濾效果。
優化文件佈局
在大數據存儲中,文件佈局優化是一種重要的性能優化技術。其主要目的是在數據寫入時將數據按照一定的規則佈局到存儲介質中,以提高數據讀取和處理的效率。文件佈局優化可以採用多種方式,如時間戳排序、分區排序和合併文件等方式。
Hudi 提供了一種名為 Clustering 的文件佈局優化方法,可以藉此將小文件合併成較大的文件以減少查詢引擎需要掃描的文件總數,或者利用空間填充曲線之類的概念來適應數據湖佈局並減少查詢讀取的數據量。利用 Clustering,可以將具有相同查詢特征的數據放到相鄰的幾個文件內,在查詢時再根據索引信息進行過濾,能夠有效減少需要讀取的文件數量,降低計算成本。
袋鼠雲數棧提供了可視化頁面以方便用戶對文件佈局進行調整,用戶可以根據需要自由設置排序策略、排序欄位、過濾條件等,如下圖所示,應用程式會周期性地在後臺根據配置對文件進行優化。因為 Hudi 採用多版本組織文件,用戶不需要擔心優化任務會影響正在運行的讀取任務,在優化完成後新的讀取任務即可享受到新的佈局帶來的效率提升。
探索新特性
在落地 Hudi 的過程中,袋鼠雲數棧也在積極跟蹤實踐社區的新功能新特性。
在 Hudi 0.13.0 中,Hudi 實現了“優化記錄負載處理”的特性。通過設置 hoodie.datasource.write.record.merger.impls=org.apache.hudi.HoodieSparkRecordMerger 和 hoodie.logfile.data.block.format=parquet 兩個參數避免了額外的複製和反序列化,在寫入操作的整個生命周期內以統一的方式處理記錄。
袋鼠雲數棧測試和引入了這項特性,經過驗證,更新性能相比上一版本有了約20%的提升,符合社區的描述。另外,數棧還參考了 Hudi 0.13.0 引入的 disruptor 無鎖消息隊列寫入數據的新特性,通過設置 hoodie.write.executor.type = DISRUPTOR 和 hoodie.write.executor.disruptor.wait.strategy = BUSY_SPIN_WAIT 參數,結合前述的優化配置,更新性能整體提升了30%以上。
總結
Apache Hudi 的優勢在於支持增量數據處理,具有良好的數據一致性和可靠性,同時提供多種性能優化技術,能夠提高數據處理和查詢的效率,具有良好的性能和可擴展性。
袋鼠雲數棧團隊在落地 Hudi 的過程中,驗證了 Hudi 的多種索引,應用了文件組織優化功能,總結了常用的調優參數,為推動企業數據湖建設,提供可靠、高效、可擴展的數據湖解決方案積累了不少經驗,能夠幫助企業更好地管理和分析數據,提高業務決策的精度和效率。
《數棧產品白皮書》:https://www.dtstack.com/resources/1004?src=szsm
《數據治理行業實踐白皮書》下載地址:https://www.dtstack.com/resources/1001?src=szsm
想瞭解或咨詢更多有關袋鼠雲大數據產品、行業解決方案、客戶案例的朋友,瀏覽袋鼠雲官網:https://www.dtstack.com/?src=szbky
同時,歡迎對大數據開源項目有興趣的同學加入「袋鼠雲開源框架釘釘技術qun」,交流最新開源技術信息,qun號碼:30537511,項目地址:https://github.com/DTStack