基於Apache Hudi + MinIO 構建流式資料湖

danny_2018發表於2022-10-11

Apache Hudi 是一個流式資料湖平臺,將核心倉庫和資料庫功能直接引入資料湖。Hudi 不滿足於將自己稱為 Delta 或 Apache Iceberg 之類的開放檔案格式,它提供表、事務、更新/刪除、高階索引、流式攝取服務、資料聚簇/壓縮最佳化和併發性。Hudi 於 2016 年推出,牢牢紮根於 Hadoop 生態系統,解釋了名稱背後的含義:Hadoop Upserts Deletes and Incrementals。它是為管理 HDFS 上大型分析資料集的儲存而開發的。Hudi 的主要目的是減少流資料攝取過程中的延遲。

隨著時間的推移,Hudi 已經發展到使用雲端儲存和物件儲存,包括 MinIO。Hudi 從 HDFS 的轉變與世界的大趨勢齊頭並進,將傳統的 HDFS 拋在腦後,以實現高效能、可擴充套件和雲原生物件儲存。Hudi 承諾提供最佳化,使 Apache Spark、Flink、Presto、Trino 和其他的分析工作負載更快,這與 MinIO 對大規模雲原生應用程式效能的承諾非常吻合。在生產中使用 Hudi 的公司包括 Uber、亞馬遜、位元組跳動和 Robinhood。這些是世界上一些最大的流式資料湖。Hudi 在這個用例中的關鍵在於它提供了一個增量資料處理棧,可以對列資料進行低延遲處理。通常系統使用 Apache Parquet 或 ORC 等開放檔案格式將資料寫入一次,並將其儲存在高度可擴充套件的物件儲存或分散式檔案系統之上。Hudi 作為資料平面來攝取、轉換和管理這些資料。Hudi 使用 Hadoop FileSystem API[7] 與儲存互動,該 API 與從 HDFS 到物件儲存到記憶體檔案系統的各種實現相容。

Hudi 檔案格式

Hudi 使用基本檔案和增量日誌檔案來儲存對給定基本檔案的更新/更改。基本檔案可以是 Parquet(列)或 HFile(索引),增量日誌儲存為 Avro(行),因為在發生更改時記錄對基本檔案的更改是有意義的。Hudi 將給定基本檔案的所有更改編碼為一系列塊。塊可以是資料塊、刪除塊或回滾塊。這些塊被合併以便派生更新的基礎檔案。這種編碼還建立了一個獨立的日誌。

表格式由表的檔案佈局、表的模式(Schema)和跟蹤表更改的後設資料組成。Hudi 強制執行模式寫入,與強調流處理一致,以確保管道不會因非向後相容的更改而中斷。Hudi 將給定表/分割槽的檔案分組在一起,並在記錄鍵和檔案組之間進行對映。如上所述,所有更新都記錄到特定檔案組的增量日誌檔案中。這種設計比 Hive ACID 更高效,後者必須將所有資料記錄與所有基本檔案合併以處理查詢。Hudi 的設計預計基於鍵的快速更新插入和刪除,因為它使用檔案組的增量日誌,而不是整個資料集。

時間線對於理解Hudi至關重要,因為它是所有 Hudi 表後設資料的真實事件日誌的來源。時間線儲存在 .hoodie 資料夾中,在我們的例子中是儲存桶。事件將保留在時間線上直到它們被刪除。整個表和檔案組都存在時間線,透過將增量日誌應用於原始基本檔案,可以重建檔案組。為了最佳化頻繁的寫入/提交,Hudi 的設計使後設資料相對於整個表的大小保持較小。時間線上的新事件被儲存到內部後設資料表中,並作為一系列讀取時合併的表實現,從而提供低寫入放大。因此,Hudi 可以快速吸收後設資料的快速變化。此外後設資料表使用 HFile 基本檔案格式,透過一組索引鍵查詢進一步最佳化效能,避免讀取整個後設資料表。作為表一部分的所有物理檔案路徑都包含在後設資料中,以避免昂貴且耗時的雲檔案列表。

Hudi寫入

Hudi 寫入架構具有 ACID 事務支援的高效能寫入層,可實現非常快速的增量更改,例如更新和刪除。典型的 Hudi 架構依賴 Spark 或 Flink 管道將資料傳遞到 Hudi 表。Hudi 寫入路徑經過最佳化,比簡單地將 Parquet 或 Avro 檔案寫入磁碟更有效。Hudi 分析寫入操作並將它們分類為增量操作(insert, upsert, delete)或批次操作(insert_overwrite, insert_overwrite_table, delete_partition, bulk_insert),然後應用必要的最佳化[8]。Hudi 寫入器還負責維護後設資料。對於每條記錄,都會寫入該記錄唯一的提交時間和序列號(這類似於 Kafka 偏移量),從而可以派生記錄級別的更改。使用者還可以在傳入資料流中指定事件時間欄位,並使用後設資料和 Hudi 時間線跟蹤它們。這可以顯著改進流處理,因為 Hudi 包含每個記錄的到達時間和事件時間,從而可以為複雜的流處理管道構建強大的水印[9]。

Hudi讀取

寫入器和讀取器之間的快照隔離允許從所有主要資料湖查詢引擎(包括 Spark、Hive、Flink、Prest、Trino 和 Impala)中一致地查詢錶快照。與 Parquet 和 Avro 一樣,Hudi 表可以被 Snowflake[10] 和 SQL Server[11] 等作為外部表讀取。Hudi 讀取器非常輕量,儘可能使用特定於引擎的向量化讀取器和快取,例如 Presto 和 Spark。當 Hudi 必須為查詢合併基本檔案和日誌檔案時,Hudi 使用可溢位對映和延遲讀取等機制提高合併效能,同時還提供讀取最佳化查詢。Hudi 包含許多非常強大的增量查詢功能,後設資料是其中的核心,允許將大型提交作為較小的塊使用,並完全解耦資料的寫入和增量查詢。透過有效使用後設資料,時間旅行非常容易實現,其只是另一個具有定義起點和終點的增量查詢。Hudi 在任何給定時間點以原子方式將鍵對映到單個檔案組,支援 Hudi 表上的完整 CDC 功能。正如上面 Hudi 寫入器部分所討論的,每個表都由檔案組組成,每個檔案組都有自己的自包含後設資料。

Hudi核心特性

Hudi 最大的優勢在於它攝取流式和批處理資料的速度。透過提供 upsert 功能,Hudi 執行任務的速度比重寫整個表或分割槽快幾個數量級。為了利用 Hudi 的攝取速度,資料湖庫需要一個具有高 IOPS 和吞吐量的儲存層。MinIO 的可擴充套件性和高效能的結合正是 Hudi 所需要的。MinIO 能夠滿足為實時企業資料湖提供動力所需的效能——最近的一項基準測試[12]在 GET 上實現了 325 GiB/s (349 GB/s),在 PUT 上實現了 165 GiB/s (177 GB/s) 32 個現成的 NVMe SSD 節點。活躍的企業 Hudi 資料湖儲存大量小型 Parquet 和 Avro 檔案。MinIO 包括許多小檔案最佳化[13],可實現更快的資料湖。小物件與後設資料一起儲存,減少了讀取和寫入小檔案(如 Hudi 後設資料和索引)所需的 IOPS。模式(Schema) 是每個 Hudi 表的關鍵元件。Hudi 可以強制執行模式,也可以允許模式演變,以便流資料管道可以適應而不會中斷。此外Hudi 強制執行 Schema-on-Writer 以確保更改不會破壞管道。Hudi 依靠 Avro 來儲存、管理和發展表的模式。Hudi 為資料湖提供 ACID 事務保證。Hudi 確保原子寫入:以原子方式向時間線提交提交,並給出一個時間戳,該時間戳表示該操作被視為發生的時間。Hudi 隔離了寫入器、表 和 讀取器程式之間的快照,因此每個程式都對錶的一致快照進行操作。Hudi 透過寫入器之間的樂觀併發控制 (OCC) 以及表服務和寫入器之間以及多個表服務之間的基於 MVCC 的非阻塞併發控制來完善這一點。

來自 “ ApacheHudi ”, 原文作者:ApacheHudi;原文連結:https://mp.weixin.qq.com/s/jBciMVsdWmRHRjEyyckQlQ,如有侵權,請聯絡管理員刪除。

相關文章