Apache Hudi 1.1.0 是一個重大版本更新,為平台帶來了顯著的性能提升、新功能和重要變更。此版本重點增強了表格式支持、改進了索引功能、擴展了引擎支持,並改進了記錄合併 API。
發佈重點
- 可插拔表格格式框架- 多種表格格式的原生集成與統一的元數據管理
- 支持 Spark 4.0 和 Flink 2.0 - 全面支持最新主要計算引擎版本
- 增強型索引- 分區記錄索引、分區級桶索引、原生 HFile 寫入器和列統計信息 V2
- 性能提升——Flink寫入吞吐量提升2-3倍,元數據表讀取速度提升4倍
- 表服務優化- Parquet 二進制複製和增量調度以實現壓縮/聚簇
- 基於存儲的鎖提供程序- 無需外部依賴的多寫入器併發控制
- 記錄合併演進——棄用有效負載類,轉而採用合併模式和合並 API
新功能
表格格式
可插拔表格式支持
Hudi 1.1.0 引入了全新的可插拔表格式框架,實現了系統內多種表格式的原生集成。該框架包含一個可插拔表格式的基礎接口,旨在簡化擴展並實現不同存儲後端之間的無縫互操作性。元數據表 (MDT) 集成也得到了增強,以支持可插拔性,確保所有受支持的表格式的模塊化和統一的元數據管理。
此版本通過新框架引入了 Hudi 的原生集成,使用户能夠直接利用 Hudi 的高級功能,同時保持語義和性能的一致性。默認情況下,配置設置hoodie.table.format為nativeHudi 表格格式。現有和新建的 Hudi 表格均無需進行任何配置更改。隨着未來版本對更多表格格式的支持,用户可以設置此配置以使其原生兼容其他格式。Apache XTable(孵化中)為 Iceberg 和 Delta Lake 等格式提供了可插拔的格式適配器。
表版本 9(帶索引版本控制)
Hudi 1.1.0 引入了表版本 9,並支持索引版本控制。元數據表中的索引(列統計信息、二級索引、表達式索引等)現在支持版本跟蹤。在 1.1.0 版本中,這些索引使用 V2 佈局,並增強了功能,包括全面的邏輯數據類型支持。從舊版本遷移的表將保留 V1 索引布局,而使用 1.1.0 創建的新表將使用 V2 佈局。兩個版本均保持向下兼容,升級到 1.1.0 時無需任何操作。
索引
分區記錄索引
除了 0.14.0 版本中引入的全局記錄索引之外,Hudi 1.1.0 還新增了一個分區索引,保證了分區路徑和記錄鍵對的唯一性。該索引能夠加快對超大型分區數據集的查找速度。更多詳情請參閲記錄索引[3]。
在 1.1.0 版本之前,僅提供全局記錄索引,配置方式如下:
hoodie.metadata.record.index.enable=true
hoodie.index.type=RECORD_INDEX
從 1.1.0 版本開始,全局版本和分區版本均可用:
對於分區記錄索引:
-
元數據表:
hoodie.metadata.record.level.index.enable=true -
寫入索引:
hoodie.index.type=RECORD_LEVEL_INDEX
全局記錄索引:
-
元數據表:
hoodie.metadata.global.record.level.index.enable=true -
寫入索引:
hoodie.index.type=GLOBAL_RECORD_LEVEL_INDEX
分區級桶索引
一種新的存儲桶索引類型,旨在解決存儲桶重新擴展的挑戰。用户可以通過規則引擎(正則表達式模式匹配)為不同的分區設置特定的存儲桶編號。現有的存儲桶索引表可以平滑無縫地升級。
主要配置:
-
hoodie.bucket.index.partition.rule.type- 表達式規則解析器(默認:正則表達式) -
hoodie.bucket.index.partition.expressions- 表達式和桶號對 -
hoodie.bucket.index.num.buckets- 分區默認存儲桶數量
原生 HFile 寫入器
Hudi 現在內置了 HFile 寫入器,消除了對 HBase 的依賴,同時確保與 HBase 的 HFile 讀取器和 Hudi 的原生讀取器兼容。這顯著減小了 Hudi 二進制包的大小,並增強了 Hudi 優化 HFile 性能。
HFile性能增強
多項改進措施,旨在加快元數據表讀取速度:
-
HFile 塊緩存(默認啓用):在同一 JVM 內重複讀取 HFile 數據塊時對其進行緩存,基準測試顯示速度提升約 4 倍。配置方法如下:
hoodie.hfile.block.cache.enabled -
HFile 預取:對於小於 50MB 的文件(可通過配置
hoodie.metadata.file.cache.max.size.mb),會預先下載整個 HFile 文件,而不是多次 RPC 調用。 -
布隆過濾器支持:通過避免不必要的塊下載來加快 HFile 查找速度。配置方式
hoodie.metadata.bloom.filter.enable
列統計信息 V2,增強了數據類型支持
列統計信息 V2 顯著提升了寫入和統計信息收集期間對邏輯數據類型的支持。諸如帶精度/小數位數的十進制數和時間戳等邏輯類型現在可以保留正確的元數據,從而提高查詢規劃和謂詞下推的準確性。
表服務
Parquet 二進制複製
這項優化使得在聚簇等操作期間可以直接從 Parquet 文件中複製 RowGroup 級別的數據,從而繞過了耗時的壓縮/解壓縮、編碼/解碼以及列到行的轉換。該優化支持正確的模式演化,並確保 Hudi 元數據能夠被正確收集和聚合。實驗結果表明,聚類操作的計算量減少了 95% 。
增量式表服務調度
顯著提升對具有大量分區的表進行壓縮和聚簇操作的性能。增量調度不再在每次調度運行時掃描所有分區,而是僅處理自上次完成的表服務操作以來發生更改的分區。默認情況下通過以下方式啓用hoodie.table.services.incremental.enabled
併發控制
基於存儲的鎖提供商
新的基於存儲的鎖提供程序使 Hudi 能夠直接使用.hoodie底層存儲中的目錄來管理多寫入者併發,從而無需 DynamoDB 或 ZooKeeper 等外部鎖提供程序。目前支持 S3 和 GCS,鎖信息維護在 <lock_name>目錄下.hoodie/.lock。更多詳情,請參閲“基於存儲的鎖提供程序”。
寫入與讀取端
多個排序字段
支持使用逗號分隔的列表來設置多個排序字段(也稱為預合併字段,該名稱已棄用)。當記錄具有相同的鍵時,Hudi 會按順序比較這些字段,並保留具有最新值的記錄。
配置:hoodie.table.ordering.fields = field1,field2,field3
高效的數據塊流式讀取
支持高效流式讀取 HoodieDataBlocks(目前為 AvroDataBlock)可減少內存使用量,提高 HDFS 上的讀取穩定性,並降低讀取日誌文件時出現超時和 OOM 錯誤的風險。
FileGroupReader 中的 ORC 支持
HoodieFileGroupReader 增強了對多種基本文件格式(ORC 和 Parquet)的支持。1.1.0 版本引入了 SparkColumnarFileReader 接口 和 MultipleColumnarFileFormatReader,以統一處理 Merge-on-Read (MOR) 和 Copy-on-Write (COW) 表中的 ORC 和 Parquet 記錄。
Hive Schema 演化支持
現在當使用寫時模式時,Hive 讀取器可以處理模式演變。
Spark
Spark 4.0 支持
Spark 4.0 現已支持,並進行了必要的兼容性和依賴項更改。可通過新hudi-spark4.0-bundle_2.13版本組件獲取。更多詳情請參閲Spark 快速入門[9]。
元數據表流式寫入
流式寫入元數據表可以在同一執行鏈中處理數據表和元數據表的寫入操作,從而提高元數據記錄的生成效率,避免按需查找。默認情況下,Spark 已啓用此功能hoodie.metadata.streaming.write.enabled。
SQL 過程增強
新的清理流程:
-
show_cleans- 顯示已完成的清理操作及其元數據 -
show_clean_plans- 顯示所有狀態(已請求、進行中、已完成)的正常操作 -
show_cleans_metadata- 提供分區級清潔詳情
增強功能:
-
run_clustering通過partition_regex_pattern參數支持正則表達式模式 -
SHOW具有高級謂詞表達式的所有非操作過程的基本路徑和過濾器參數
Flink
支持 Flink 2.0
全面支持 Flink 2.0,包括 sink、read、catalog 和新的 bundle artifact hudi-flink2.0-bundle。修復了舊版 API 的兼容性問題,並默認支持 sinkV2 API。棄用:已移除對 Flink 1.14、1.15 和 1.16 的支持
性能改進
-
引擎原生記錄支持:無需 Avro 轉換,直接使用 RowData 實現更高效的序列化/反序列化。讀寫性能平均提升 2-3 倍。
-
異步即時時間生成:通過避免即時時間生成阻塞,顯著提高高吞吐量工作負載的穩定性。
-
元字段控制:支持
hoodie.populate.meta.fields追加模式,禁用時寫入速度提升 14%。
新功能
-
內存緩衝區排序:對於無主鍵表,可提高列式格式的壓縮率(
write.buffer.sort.enabled) -
分段速率限制:配置流式讀取每次即時檢查的最大分段數(
read.splits.limit)
產品目錄
Polaris集成
通過將表創建委託給 Polaris Spark 客户端,實現與 Polaris 目錄的集成,從而允許在 Polaris 目錄中註冊 Hudi 表。
配置:(hoodie.datasource.polaris.catalog.class默認值org.apache.polaris.spark.SparkCatalog)。更多詳情請參閲Polaris 產品目錄。
AWS Glue 和 DataHub 同步增強功能
-
CatalogId 對跨目錄場景的支持
-
顯式數據庫和表名配置
-
Glue 數據庫和表的資源標記
-
DataHub 支持 TLS/HTTPS,包括自定義 CA 證書和雙向 TLS。
平台組件
增強 HudiStreamer 的 JSON 到 Avro 轉換功能
改進了 JSON 到 Avro 的轉換層,以提高 Kafka JSON 源的可靠性。
Prometheus 多表支持
改進了 PrometheusReporter,增加了引用計數機制,以防止在停止單個表的指標時關閉共享的 HTTP 服務器。
API變更與棄用
HoodieRecordPayload 已棄用
有效載荷類現已棄用,取而代之的是合併模式和合並 API。基於有效載荷的方法與 Avro 格式的記錄緊密相關,因此與 Spark InternalRow 等原生查詢引擎格式的兼容性較差。
遷移路徑:
-
標準用例:使用合併模式配置(
COMMIT_TIME_ORDERING或EVENT_TIME_ORDERING) -
自定義邏輯:實現
HoodieRecordMerger接口而非自定義有效負載 -
自動遷移:升級到最新表版本時,已知有效負載將自動遷移到相應的合併模式。
合併模式支持:
-
提交時間和事件時間排序
-
部分更新策略(替換
OverwriteNonDefaultsWithLatestAvroPayload和PostgresDebeziumAvroPayload已標記值處理) -
跨引擎的語義合併一致性
-
性能優化
BufferedRecordMerger API:該HoodieRecordMerger接口已更新,以利用BufferedRecord記錄合併期間使用的新類。
重大變更
複雜Key生成器回退修復
已修復影響具有單個記錄鍵字段的複雜鍵生成器的回退問題。該回退問題在 0.14.1、0.15.0 和 1.0.x 版本中引入,導致記錄鍵編碼從 field_name:field_value` ` 變為 ` `field_value,這可能導致在執行 upsert 操作時出現重複記錄。
受影響對象:使用複雜鍵生成器(ComplexAvroKeyGenerator或ComplexKeyGenerator)且具有單個記錄鍵字段的表。
1.1.0 中的默認行為field_name:field_value:恢復為與0.14.0 及更早版本匹配的正確編碼格式。
遷移路徑:
-
從 ≤0.14.0 版本升級:無需任何操作,默認行為正確
-
0.15.0/1.0.x 版本中創建的新表:設置
hoodie.write.complex.keygen.new.encoding=true為保持當前編碼 -
從 0.14.0 升級到 0.15.0/1.0.x:如果遇到數據重複的問題,可能需要修復數據。修復工具預計將在 1.1.1 版本中發佈。
驗證:默認情況下,寫入操作會驗證表配置,如果受到影響則會發出警報。hoodie.write.complex.keygen.validation.enable=false如有需要,可以禁用此功能(讀取操作不受影響)。
關於表版本 9 的説明:對於升級到版本 9 的表,鍵編碼格式已鎖定,以防止將來出現回退問題,並確保記錄索引和二級索引的正確行為。
移除 WriteClient 中的自動提交支持
對於HoodieWriteClient直接使用該功能的開發者,自動提交支持已被移除。該hoodie.auto.commit配置不再生效。
需要遷移:
// Previous (with auto-commit)
HoodieWriteConfig config = // instantiate config
SparkRDDWriteClient writeClient = new SparkRDDWriteClient(engineContext, config);
String instantTime = writeClient.startCommit();
writeClient.upsert(JavaRDD<HoodieRecord>, instantTime);
// Now Required (explicit commit)
HoodieWriteConfig config = // instantiate config
SparkRDDWriteClient writeClient = new SparkRDDWriteClient(engineContext, config);
String instantTime = writeClient.startCommit();
JavaRDD<WriteStatus> writeStatus = writeClient.upsert(RDD<HoodieRecord>, instantTime);
writeClient.commit(instantTime, writeStatus); // Explicit commit now mandatory
這項變更同樣適用於表服務。
INSERT INTO 行為變更
Spark SQL 命令的默認行為INSERT INTO已更改。此前對於包含排序字段的表,它會使用“upsert”操作,從而實現數據去重。從 1.1.0 版本開始,INSERT INTO默認執行“insert”操作,直接導入記錄,不進行數據去重。
例子:
Commit1:
Partition1, recordKey1, val1, orderingValue1
Partition1, recordKey1, val2, orderingValue2
Pre-1.1.0: Returns one record (based on ordering field)
From 1.1.0: Returns both records
要恢復之前的行為:設置hoodie.spark.sql.insert.into.operation = upsert
使用簡易桶式 COW 的多個Bulk Insert的限制
當滿足以下所有條件時bulk_insert,對寫時複製表的多項操作將受到限制:
-
1. 表格類型為 COW
-
2. 索引類型
BUCKET為引擎設置為SIMPLE -
3. Spark 原生行寫入器已禁用(
hoodie.datasource.write.row.writer.enable = false)
解決方法:upsert在初始操作之後使用操作bulk_insert,或者啓用 Spark 原生行寫入器。
Flink 桶索引限制
桶索引現在僅支持 UPSERT 操作,不能與 Flink 中的追加寫入模式一起使用。
行為變更
默認合併模式已更改
默認的記錄合併行為已根據是否設置了排序字段而改變:
-
無排序字段:默認
COMMIT_TIME_ORDERING使用OverwriteWithLatestAvroPayload(後寫優先) -
排序字段集:默認
EVENT_TIME_ORDERING使用DefaultHoodieRecordPayload(經典的基於事件時間的比較)
用户應使用hoodie.table.ordering.fields(hoodie.datasource.write.precombine.field已棄用)。
hoodie.datasource.write.precombine.field(先前)的默認值ts已被移除。
變更原因:之前的默認設置要求用户ts即使在簡單的 upsert 操作(即後寫優先)中也必須在模式中包含一個字段。新的行為使得 Hudi 能夠開箱即用地處理簡單的 upsert 操作,同時在顯式配置的情況下仍然支持事件時間排序。
對 HoodieStreamer 的影響:該--source-ordering-field參數不再默認為ts。
-
之前:自動啓用
EVENT_TIME_ORDERING -
現在:
COMMIT_TIME_ORDERING如果未指定,則使用默認值 -
需要採取的操作:對於需要事件時間合併的新 Deltastreamer 作業,請明確提供
--source-ordering-field ts(或你的排序字段)。
驗證變更:配置不匹配現在會記錄警告,而不是導致作業失敗:
-
使用
COMMIT_TIME_ORDERING排序字段時,會記錄一條警告,提示該字段已被忽略。 -
不使用
EVENT_TIME_ORDERING排序字段時,系統會記錄警告而不是報錯。
增量查詢回退行為
默認值hoodie.datasource.read.incr.fallback.fulltablescan.enable已從更改false為true。現在,找不到必要提交/數據文件的增量查詢將自動回退到全表掃描,而不是失敗。
性能影響:以前快速失敗的查詢現在會成功,但由於全表掃描,運行速度可能會明顯變慢。
要恢復快速失敗行為:設置hoodie.datasource.read.incr.fallback.fulltablescan.enable = false
增量查詢開始時間語義
配置hoodie.datasource.read.begin.instanttime行為已恢復為互斥(與 0.x 版本行為一致),糾正了 1.0.0 版本中引入的包含行為。
時間戳邏輯類型處理
列統計信息 V2 版本現已正確處理時間戳字段(與 0.15.0 及更早的 1.x 版本timestamp_millis不同timestamp_micros)。此版本在讀取使用舊版本編寫的表時保持向後兼容性。
Flink 桶索引追加模式限制
桶索引現在僅支持 UPSERT 操作,不能與 Flink 中的追加寫入模式一起使用。
升級説明
-
檢查複雜Key生成器使用情況:從 0.14.0 或更早版本升級的用户應檢查其配置。
-
更新 WriteClient 用法:如果直接使用
HoodieWriteClient,請添加顯式提交調用 -
檢查 INSERT INTO 行為:驗證您的管道是否依賴於舊的 upsert 行為
-
檢查合併模式配置:尤其是在新建表格或使用 HoodieStreamer 時。
-
測試增量查詢:注意新的回退行為及其潛在的性能影響
-
Flink 版本:請確保您使用的是 Flink 1.17 或更高版本,或 2.0 版本(1.14-1.16 版本已不再支持)。
Hudi 版本支持
Hudi 0.14.0 之前的版本已停止維護
自本次發佈起,Hudi 0.14.0 之前的版本已停止維護。使用這些舊版本的用户應計劃升級到 1.1.0 或更高版本,以獲得持續的支持、錯誤修復和新功能。Hudi 社區將把支持工作重點放在 0.14.0 及更高版本上。