Hudi 核心知識點詳解(一)
- 1.數據湖與數據倉庫的區別 ?
- 1.1 數據倉庫
- 1.2 數據湖
- 1.3 兩者的區別
- 2.Hudi 基礎功能
- 2.1 Hudi 簡介
- 2.2 Hudi 功能
- 2.3 Hudi 的特性
- 2.4 Hudi 的架構
- 2.5 湖倉一體架構
- 3.Hudi 數據管理
- 3.1 Hudi 表數據結構
- 3.1.1 .hoodie 文件
- 3.1.2 數據文件
- 3.2 數據存儲概述
- 3.3 Metadata 元數據
- 3.4 Index 索引
- 索引策略
- 工作負載 1:對事實表
- 工作負載 2:對事件表
- 工作負載 3:隨機更新 / 刪除維度表
- 3.5 Data 數據
在 Flink 實時流中,經常會通過 Flink CDC 插件讀取 Mysql 數據,然后寫入 Hudi 中。所以在執行上述操作時,需要了解 Hudi 的基本概念以及操作原理,這樣在近實時往 Hudi 中寫數據時,遇到報錯問題,才能及時處理。
接下來將從以下幾方面全面闡述 Hudi 組件核心知識點。
- 數據湖與數據倉庫的區別 ?
- Hudi 基礎功能
- Hudi 數據管理
- Hudi 核心點解析
1.數據湖與數據倉庫的區別 ?
1.1 數據倉庫
-
數據倉庫(英語:
Data Warehouse
,簡稱:數倉、DW),是一個用于 存儲、分析、報告 的數據系統。 -
數據倉庫的目的是構建面向分析的集成化數據環境,分析結果為企業提供 決策支持(
Decision Support
)。
1.2 數據湖
-
數據湖(
Data Lake
)和數據庫、數據倉庫一樣,都是數據存儲的設計模式,現在企業的數據倉庫都會通過分層的方式將數據存儲在文件夾、文件中。 -
數據湖是一個集中式數據存儲庫,用來存儲大量的原始數據,使用平面架構來存儲數據。
-
定義:一個以原始格式(通常是對象塊或文件)存儲數據的系統或存儲庫,通常是所有企業數據的單一存儲。
-
數據湖可以包括來自關系數據庫的結構化數據(行和列)、半結構化數據(CSV、日志、XML、JSON)、非結構化數據(電子郵件、文檔、PDF)和二進制數據(圖像、音頻、視頻)。
-
數據湖中數據,用于報告、可視化、高級分析和機器學習等任務。
1.3 兩者的區別
-
數據倉庫是一個優化的數據庫,用于分析來自事務系統和業務線應用程序的關系數據。
-
數據湖存儲來自業務線應用程序的關系數據,以及來自移動應用程序、IoT 設備和社交媒體的非關系數據。
特性 | | |
---|---|---|
數據 | 來自事務系統、運營數據庫和業務線應用程序的關系數據 | 來自 IoT 設備、網站、移動應用程序、社交媒體和企業應用程序的非關系和關系數據 |
Schema | 設計在數據倉庫實施之前(寫入型 Schema) | 寫入在分析時(讀取型 Schema) |
性價比 | 更快查詢結果會帶來較高存儲成本 | 更快查詢結果只需較低存儲成本 |
數據質量 | 可作為重要事實依據的高度監管數據 | 任何可以或無法進行監管的數據(例如原始數據) |
用戶 | 業務分析師 | 數據科學家、數據開發人員和業務分析師(使用監管數據) |
分析 | 批處理報告、BI和可視化 | 機器學習、預測分析、數據發現和分析 |
數據湖并不能替代數據倉庫,數據倉庫在高效的報表和可視化分析中仍有優勢。
2.Hudi 基礎功能
2.1 Hudi 簡介
Apache Hudi 由 Uber 開發并開源,該項目在 2016 年開始開發,并于 2017 年開源,2019 年 1 月進入 Apache 孵化器,且 2020 年 6 月稱為 Apache 頂級項目,目前最新版本:0.10.1
版本。
Hudi 一開始支持 Spark 進行數據攝入(批量 Batch 和流式 Streaming),從 0.7.0
版本開始,逐漸與 Flink 整合,主要在于 Flink SQL 整合,還支持 Flink SQL CDC。
Hudi(Hadoop Upserts anD Incrementals 的縮寫),是目前市面上流行的三大開源數據湖方案之一。
用于管理分布式文件系統 DFS 上大型分析數據集存儲。
簡單來說,Hudi 是一種針對分析型業務的、掃描優化的數據存儲抽象,它能夠使 DFS 數據集在分鐘級的時延內支持變更,也支持下游系統對這個數據集的增量處理。
2.2 Hudi 功能
- ? Hudi 是在大數據存儲上的一個數據集,可以將 Change Logs 通過
upsert
的方式合并進 Hudi。 - ? Hudi 對上可以暴露成一個普通 Hive 或 Spark 表,通過 API 或命令行可以獲取到增量修改的信息,繼續供下游消費。
- ? Hudi 保管修改歷史,可以做時間旅行或回退。
- ? Hudi 內部有主鍵到文件級的索引,默認是記錄到文件的布隆過濾器。
2.3 Hudi 的特性
Apache Hudi 使得用戶能在 Hadoop 兼容的存儲之上存儲大量數據,同時它還提供兩種原語,不僅可以 批處理,還可以在數據湖上進行 流處理。
1?? Update
/ Delete
記錄:Hudi 使用細粒度的文件 / 記錄級別索引來支持 Update
/ Delete
記錄,同時還提供寫操作的事務保證。查詢會處理最后一個提交的快照,并基于此輸出結果。
2?? 變更流:Hudi 對獲取數據變更提供了一流的支持:可以從給定的 時間點 獲取給定表中已 updated
/ inserted
/ deleted
的所有記錄的增量流,并解鎖新的查詢姿勢(類別)。
- ? Apache Hudi 本身不存儲數據,僅僅管理數據。
- ? Apache Hudi 也不分析數據,需要使用計算分析引擎,查詢和保存數據,比如 Spark 或 Flink。
- ? 使用 Hudi 時,加載
jar
包,底層調用 API,所以需要依據使用大數據框架版本,編譯 Hudi 源碼,獲取對應依賴jar
包。
2.4 Hudi 的架構
- ? 通過 DeltaStreammer、Flink、Spark 等工具,將數據攝取到數據湖存儲,可使用 HDFS 作為數據湖的數據存儲。
- ? 基于 HDFS 可以構建 Hudi 的數據湖。
- ? Hudi 提供統一的訪問 Spark 數據源和 Flink 數據源。
- ? 外部通過不同引擎,如:Spark、Flink、Presto、Hive、Impala、Aliyun DLA、AWS Redshit 訪問接口。
2.5 湖倉一體架構
Hudi 對于 Flink 友好支持以后,可以使用 Flink + Hudi 構建實時湖倉一體架構,數據的時效性可以到分鐘級,能很好的滿足業務準實時數倉的需求。
通過湖倉一體、流批一體,準實時場景下做到了:數據同源、同計算引擎、同存儲、同計算口徑。
3.Hudi 數據管理
3.1 Hudi 表數據結構
Hudi 表的數據文件,可以使用操作系統的文件系統存儲,也可以使用 HDFS 這種分布式的文件系統存儲。為了后續分析性能和數據的可靠性,一般使用 HDFS 進行存儲。以 HDFS 存儲來看,一個 Hudi 表的存儲文件分為兩類。
.hoodie
文件:由于 CRUD 的零散性,每一次的操作都會生成一個文件,這些小文件越來越多后,會嚴重影響 HDFS 的性能,Hudi 設計了一套文件合并機制。.hoodie
文件夾中存放了對應的 文件合并操作 相關的日志文件。amricas
和asia
相關的路徑是 實際的數據文件,按分區存儲,分區的路徑key
是可以指定的。
3.1.1 .hoodie 文件
Hudi 把隨著時間流逝,對表的一系列 CRUD 操作叫做 Timeline,Timeline 中某一次的操作,叫做 Instant。
Hudi 的核心是維護 Timeline 在不同時間對表執行的所有操作,Instant 這有助于提供表的即時視圖,同時還有效地支持按到達順序檢索數據。Hudi Instant 由以下組件組成:
Instant Action
:記錄本次操作是一次操作類型,數據提交(COMMITS
),還是 文件合并(COMPACTION
),或者是 文件清理(CLEANS
)。Instant Time
:本次操作發生的時間,通常是時間戳(例如:20190117010349),它按照動作開始時間的順序單調遞增。State
:操作的狀態,發起(REQUESTED
),進行中(INFLIGHT
),還是 已完成(COMPLETED
)。
.hoodie
文件夾中存放對應操作的狀態記錄:
3.1.2 數據文件
Hudi 真實的數據文件使用 Parquet
文件格式存儲。
其中包含一個 metadata
元數據文件和數據文件 parquet
列式存儲。
Hudi 為了實現數據的 CRUD,需要能夠唯一標識一條記錄,Hudi 將把數據集中的 唯一字段(record key
)+ 數據所在分區(partition Path
)聯合起來當做 數據的唯一鍵。
3.2 數據存儲概述
Hudi 數據集的 組織目錄結構 與 Hive 表示非常相似,一份數據集對應這一個根目錄。數據集被 打散為多個分區,分區字段以文件夾形式存在,該文件夾包含該分區的所有文件。
在根目錄下,每個分區都有唯一的分區路徑,每個分區數據存儲在多個文件中。
每個文件都有唯一的 fileId
和生成文件的 commit
標識。如果發生更新操作時,多個文件共享相同的 fileId
,但會有不同的 commit
。
3.3 Metadata 元數據
以 時間軸(Timeline
)的形式將數據集上的各項操作元數據維護起來,以支持數據集的瞬態視圖,這部分元數據存儲于根目錄下的元數據目錄。一共有三種類型的元數據:
- Commits:一個單獨的
commit
包含對數據集之上一批數據的一次原子寫入操作的相關信息。我們用單調遞增的時間戳來標識commits
,標定的是一次寫入操作的開始。 - Cleans:用于清除數據集中不再被查詢所用到的舊版本文件的后臺活動。
- Compactions:用于協調 Hudi 內部的數據結構差異的后臺活動。例如,將更新操作由基于行存的日志文件歸集到列存數據上。
3.4 Index 索引
Hudi 維護著一個索引,以支持在記錄 key
存在情況下,將新記錄的 key
快速映射到對應的 fileId
。
- Bloom filter:存儲于數據文件頁腳。默認選項,不依賴外部系統實現。數據和索引始終保持一致。
- Apache HBase:可高效查找一小批
key
。在索引標記期間,此選項可能快幾秒鐘。
索引策略
工作負載 1:對事實表
許多公司將大量事務數據存儲在 NoSQL 數據存儲中。例如,拼車情況下的行程表、股票買賣、電子商務網站中的訂單。這些表通常會隨著對最新數據的隨機更新而不斷增長,而長尾更新會針對較舊的數據,這可能是由于交易在以后結算 / 數據更正所致。換句話說,大多數更新進入最新的分區,很少有更新進入較舊的分區。
對于這樣的工作負載,BLOOM 索引表現良好,因為索引查找 將基于大小合適的布隆過濾器修剪大量數據文件。此外,如果可以構造鍵,以使它們具有一定的順序,則要比較的文件數量會通過范圍修剪進一步減少。
Hudi 使用所有文件鍵范圍構建一個區間樹,并有效地過濾掉更新 / 刪除記錄中與任何鍵范圍不匹配的文件。
為了有效地將傳入的記錄鍵與布隆過濾器進行比較,即最小數量的布隆過濾器讀取和跨執行程序的統一工作分配,Hudi 利用輸入記錄的緩存并采用可以使用統計信息消除數據偏差的自定義分區器。有時,如果布隆過濾器誤報率很高,它可能會增加混洗的數據量以執行查找。
Hudi 支持動態布隆過濾器(使用啟用 hoodie.bloom.index.filter.type=DYNAMIC_V0
),它根據存儲在給定文件中的記錄數調整其大小,以提供配置的誤報率。
工作負載 2:對事件表
事件流無處不在。來自 Apache Kafka 或類似消息總線的事件通常是事實表大小的 10 ? 100 10-100 10?100 倍,并且通常將 時間(事件的到達時間 / 處理時間)視為一等公民。
例如,物聯網事件流、點擊流數據、廣告印象 等。插入和更新僅跨越最后幾個分區,因為這些大多是僅附加數據。鑒于可以在端到端管道中的任何位置引入重復事件,因此在存儲到數據湖之前進行重復數據刪除是一項常見要求。
一般來說,這是一個非常具有挑戰性的問題,需要以較低的成本解決。雖然,我們甚至可以使用鍵值存儲來使用 HBASE 索引執行重復數據刪除,但索引存儲成本會隨著事件的數量線性增長,因此可能會非常昂貴。
實際上,BLOOM 帶有范圍修剪的索引是這里的最佳解決方案。人們可以利用時間通常是一等公民這一事實并構造一個鍵,event_ts
+ event_id
例如插入的記錄具有單調遞增的鍵。即使在最新的表分區中,也可以通過修剪大量文件來產生巨大的回報。
工作負載 3:隨機更新 / 刪除維度表
這些類型的表格通常包含高維數據并保存參考數據,例如 用戶資料、商家信息。這些是高保真表,其中更新通常很小,但也分布在許多分區和數據文件中,數據集從舊到新。通常,這些表也是未分區的,因為也沒有對這些表進行分區的好方法。
如前所述,BLOOM 如果無法通過比較范圍 / 過濾器來刪除大量文件,則索引可能不會產生好處。在這樣的隨機寫入工作負載中,更新最終會觸及表中的大多數文件,因此布隆過濾器通常會根據一些傳入的更新指示所有文件的真陽性。因此,我們最終會比較范圍 / 過濾器,只是為了最終檢查所有文件的傳入更新。
SIMPLE 索引將更適合,因為它不進行任何基于預先修剪的操作,而是直接與每個數據文件中感興趣的字段連接 。HBASE 如果操作開銷是可接受的,并且可以為這些表提供更好的查找時間,則可以使用索引。
在使用全局索引時,用戶還應該考慮設置 hoodie.bloom.index.update.partition.path=true
或 hoodie.simple.index.update.partition.path=true
處理分區路徑值可能因更新而改變的情況,例如用戶表按家鄉分區;用戶搬遷到不同的城市。這些表也是 Merge-On-Read 表類型的絕佳候選者。
3.5 Data 數據
Hudi 以兩種不同的存儲格式存儲所有攝取的數據,用戶可選擇滿足下列條件的任意數據格式:
- 讀優化的列存格式(
ROFormat
):缺省值為Apache Parquet
。 - 寫優化的行存格式(
WOFormat
):缺省值為Apache Avro
。