Hudi(3):Hudi之基本概念-創(chuàng)新互聯(lián)

目錄

創(chuàng)新互聯(lián)長期為1000多家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為通城企業(yè)提供專業(yè)的成都做網(wǎng)站、網(wǎng)站制作,通城網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

0. 相關(guān)文章鏈接

1. 時間軸(TimeLine)

1.1.?Instant action:在表上執(zhí)行的操作類型

1.2.?Instant time

1.3.?State

1.4.?兩個時間概念

2. 文件布局(File Layout)

2.1. Hudi表的文件結(jié)構(gòu)

2.2. Hudi存儲的兩個部分

2.3. Hudi的具體文件說明

3. 索引(Index)

3.1.?原理

3.2.?索引選項

3.3.?全局索引與非全局索引

3.4.?索引的選擇策略

3.4.1.?對事實表的延遲更新

3.4.2.?對事件表的去重

3.4.3.?對維度表的隨機更刪

4.?表類型(Table Types)

4.1.?Copy On Write

4.2.?Merge On Read

4.3.?COW與MOR的對比

5.?查詢類型(Query Types)

5.1.?Snapshot Queries

5.2.?Incremental Queries

5.3.?Read Optimized Queries

5.4.?不同表支持的查詢類型

6.?Compaction


0. 相關(guān)文章鏈接

Hudi文章匯總?

1. 時間軸(TimeLine)

Hudi的核心是維護表上在不同的即時時間(instants)執(zhí)行的所有操作的時間軸(timeline),這有助于提供表的即時視圖,同時還有效地支持按到達順序檢索數(shù)據(jù)。一個instant由以下三個部分組成:

1.1.?Instant action:在表上執(zhí)行的操作類型
  • COMMITS:一次commit表示將一批數(shù)據(jù)原子性地寫入一個表。
  • CLEANS:清除表中不再需要的舊版本文件的后臺活動。
  • DELTA_COMMIT:增量提交指的是將一批數(shù)據(jù)原子性地寫入一個MergeOnRead類型的表,其中部分或所有數(shù)據(jù)可以寫入增量日志。
  • COMPACTION:合并Hudi內(nèi)部差異數(shù)據(jù)結(jié)構(gòu)的后臺活動,例如:將更新操作從基于行的log日志文件合并到列式存儲的數(shù)據(jù)文件。在內(nèi)部,COMPACTION體現(xiàn)為timeline上的特殊提交。
  • ROLLBACK:表示當commit/delta_commit不成功時進行回滾,其會刪除在寫入過程中產(chǎn)生的部分文件。
  • SAVEPOINT:將某些文件組標記為已保存,以便其不會被刪除。在發(fā)生災(zāi)難需要恢復數(shù)據(jù)的情況下,它有助于將數(shù)據(jù)集還原到時間軸上的某個點。
1.2.?Instant time
  • 通常是一個時間戳(例如:20190117010349),它按照動作開始時間的順序單調(diào)增加。
1.3.?State
  • REQUESTED:表示某個action已經(jīng)調(diào)度,但尚未執(zhí)行。
  • INFLIGHT:表示action當前正在執(zhí)行。
  • COMPLETED:表示timeline上的action已經(jīng)完成。
1.4.?兩個時間概念
  • Arrival time: 數(shù)據(jù)到達 Hudi 的時間,commit time。
  • Event time: record 中記錄的時間。

上圖中采用時間(小時)作為分區(qū)字段,從 10:00 開始陸續(xù)產(chǎn)生各種 commits,10:20 來了一條 9:00 的數(shù)據(jù),根據(jù)event time該數(shù)據(jù)仍然可以落到 9:00 對應(yīng)的分區(qū),通過 timeline 直接消費 10:00 (commit time)之后的增量更新(只消費有新 commits 的 group),那么這條延遲的數(shù)據(jù)仍然可以被消費到。

2. 文件布局(File Layout) 2.1. Hudi表的文件結(jié)構(gòu)

Hudi將一個表映射為如下文件結(jié)構(gòu)

2.2. Hudi存儲的兩個部分
  • 元數(shù)據(jù):.hoodie目錄對應(yīng)著表的元數(shù)據(jù)信息,包括表的版本管理(Timeline)、歸檔目錄(存放過時的instant也就是版本),一個instant記錄了一次提交(commit)的行為、時間戳和狀態(tài),Hudi以時間軸的形式維護了在數(shù)據(jù)集上執(zhí)行的所有操作的元數(shù)據(jù);
  • 數(shù)據(jù):和hive一樣,以分區(qū)方式存放數(shù)據(jù);分區(qū)里面存放著Base File(.parquet)和Log File(.log.*);

2.3. Hudi的具體文件說明

(1)Hudi將數(shù)據(jù)表組織成分布式文件系統(tǒng)基本路徑(basepath)下的目錄結(jié)構(gòu)

(2)表被劃分為多個分區(qū),這些分區(qū)是包含該分區(qū)的數(shù)據(jù)文件的文件夾,非常類似于Hive表

(3)在每個分區(qū)中,文件被組織成文件組,由文件ID唯一標識

(4)每個文件組包含幾個文件片(FileSlice)

(5)每個文件片包含:

  • 一個基本文件(.parquet):在某個commit/compaction即時時間(instant time)生成的(MOR可能沒有)
  • 多個日志文件(.log.*),這些日志文件包含自生成基本文件以來對基本文件的插入/更新(COW沒有)

(6)Hudi采用了多版本并發(fā)控制(Multiversion Concurrency Control, MVCC)

  • compaction操作:合并日志和基本文件以產(chǎn)生新的文件片
  • clean操作:清除不使用的/舊的文件片以回收文件系統(tǒng)上的空間

(7)Hudi的base file(parquet 文件)在 footer 的 meta 去記錄了 record key 組成的 BloomFilter,用于在 file based index 的實現(xiàn)中實現(xiàn)高效率的 key contains 檢測。只有不在 BloomFilter 的 key 才需要掃描整個文件消滅假陽。

(8)Hudi 的 log (avro 文件)是自己編碼的,通過積攢數(shù)據(jù) buffer 以 LogBlock 為單位寫出,每個 LogBlock 包含 magic number、size、content、footer 等信息,用于數(shù)據(jù)讀、校驗和過濾。

3. 索引(Index) 3.1.?原理

Hudi通過索引機制提供高效的upserts,具體是將給定的hoodie key(record key + partition path)與文件id(文件組)建立唯一映射。這種映射關(guān)系,數(shù)據(jù)第一次寫入文件后保持不變,所以,一個 FileGroup 包含了一批 record 的所有版本記錄。Index 用于區(qū)分消息是 INSERT 還是 UPDATE。

Hudi 為了消除不必要的讀寫,引入了索引的實現(xiàn)。在有了索引之后,更新的數(shù)據(jù)可以快速被定位到對應(yīng)的 File Group。上圖為例,白色是基本文件,黃色是更新數(shù)據(jù),有了索引機制,可以做到:避免讀取不需要的文件、避免更新不必要的文件、無需將更新數(shù)據(jù)與歷史數(shù)據(jù)做分布式關(guān)聯(lián),只需要在 File Group 內(nèi)做合并。

3.2.?索引選項
Index類型原理優(yōu)點缺點
Bloom Index默認配置,使用布隆過濾器來判斷記錄存在與否,也可選使用record key的范圍裁剪需要的文件效率高,不依賴外部系統(tǒng),數(shù)據(jù)和索引保持一致性因假陽性問題,還需回溯原文件再查找一遍
Simple Index把update/delete操作的新數(shù)據(jù)和老數(shù)據(jù)進行join實現(xiàn)最簡單,無需額外的資源性能比較差
HBase Index把index存放在HBase里面。在插入 File Group定位階段所有task向HBase發(fā)送 Batch Get 請求,獲取 Record Key 的 Mapping 信息對于小批次的keys,查詢效率高需要外部的系統(tǒng),增加了運維壓力
Flink State-based IndexHUDI 在 0.8.0 版本中實現(xiàn)的 Flink witer,采用了 Flink 的 state 作為底層的 index 存儲,每個 records 在寫入之前都會先計算目標 bucket ID。不同于 BloomFilter Index,避免了每次重復的文件 index 查找

注意:Flink只有一種state based index(和bucket_index),其他index是Spark可選配置。

3.3.?全局索引與非全局索引

全局索引:全局索引在全表的所有分區(qū)范圍下強制要求鍵的唯一性,也就是確保對給定的鍵有且只有一個對應(yīng)的記錄。全局索引提供了更強的保證,但是隨著表增大,update/delete 操作損失的性能越高,因此更適用于小表。

非全局索引:默認的索引實現(xiàn),只能保證數(shù)據(jù)在分區(qū)的唯一性。非全局索引依靠寫入器為同一個記錄的update/delete提供一致的分區(qū)路徑,同時大幅提高了效率,更適用于大表。
從index的維護成本和寫入性能的角度考慮,維護一個global index的難度更大,對寫入性能的影響也更大,所以需要non-global index。

HBase索引本質(zhì)上是一個全局索引,bloom和simple index都有全局選項(hoodie.index.type=GLOBAL_BLOOM 和 hoodie.index.type=GLOBAL_SIMPLE)

3.4.?索引的選擇策略 3.4.1.?對事實表的延遲更新

許多公司會在NoSQL數(shù)據(jù)存儲中存放大量的交易數(shù)據(jù)。例如共享出行的行程表、股票買賣記錄的表、和電商的訂單表。這些表通常一直在增長,且大部分的更新隨機發(fā)生在較新的記錄上,而對舊記錄有著長尾分布型的更新。這通常是源于交易關(guān)閉或者數(shù)據(jù)更正的延遲性。換句話說,大部分更新會發(fā)生在最新的幾個分區(qū)上而小部分會在舊的分區(qū)。

對于這樣的作業(yè)模式,布隆索引就能表現(xiàn)地很好,因為查詢索引可以靠設(shè)置得當?shù)牟悸∵^濾器來裁剪很多數(shù)據(jù)文件。另外,如果生成的鍵可以以某種順序排列,參與比較的文件數(shù)會進一步通過范圍裁剪而減少。Hudi用所有文件的鍵域來構(gòu)造區(qū)間樹,這樣能來高效地依據(jù)輸入的更刪記錄的鍵域來排除不匹配的文件。

為了高效地把記錄鍵和布隆過濾器進行比對,即盡量減少過濾器的讀取和均衡執(zhí)行器間的工作量,Hudi緩存了輸入記錄并使用了自定義分區(qū)器和統(tǒng)計規(guī)律來解決數(shù)據(jù)的偏斜。有時,如果布隆過濾器的假陽性率過高,查詢會增加數(shù)據(jù)的打亂操作。Hudi支持動態(tài)布隆過濾器(設(shè)置hoodie.bloom.index.filter.type=DYNAMIC_V0)。它可以根據(jù)文件里存放的記錄數(shù)量來調(diào)整大小從而達到設(shè)定的假陽性率。

3.4.2.?對事件表的去重

事件流無處不在。從Apache Kafka或其他類似的消息總線發(fā)出的事件數(shù)通常是事實表大小的10-100倍。事件通常把時間(到達時間、處理時間)作為首類處理對象,比如物聯(lián)網(wǎng)的事件流、點擊流數(shù)據(jù)、廣告曝光數(shù)等等。由于這些大部分都是僅追加的數(shù)據(jù),插入和更新只存在于最新的幾個分區(qū)中。由于重復事件可能發(fā)生在整個數(shù)據(jù)管道的任一節(jié)點,在存放到數(shù)據(jù)湖前去重是一個常見的需求。

總的來說,低消耗去重是一個非常有挑戰(zhàn)的工作。雖然可以用一個鍵值存儲來實現(xiàn)去重(即HBase索引),但索引存儲的消耗會隨著事件數(shù)增長而線性增長以至于變得不可行。事實上,有范圍裁剪功能的布隆索引是最佳的解決方案。我們可以利用作為首類處理對象的時間來構(gòu)造由事件時間戳和事件id(event_ts+event_id)組成的鍵,這樣插入的記錄就有了單調(diào)增長的鍵。這會在最新的幾個分區(qū)里大幅提高裁剪文件的效益。

3.4.3.?對維度表的隨機更刪

正如之前提到的,如果范圍比較不能裁剪許多文件的話,那么布隆索引并不能帶來很好的效益。在這樣一個隨機寫入的作業(yè)場景下,更新操作通常會觸及表里大多數(shù)文件從而導致布隆過濾器依據(jù)輸入的更新對所有文件標明陽性。最終會導致,即使采用了范圍比較,也還是檢查了所有文件。使用簡單索引對此場景更合適,因為它不采用提前的裁剪操作,而是直接和所有文件的所需字段連接。如果額外的運維成本可以接受的話,也可以采用HBase索引,其對這些表能提供更加優(yōu)越的查詢效率。
當使用全局索引時,也可以考慮通過設(shè)置hoodie.bloom.index.update.partition.path=true或hoodie.simple.index.update.partition.path=true來處理 的情況;例如對于以所在城市分區(qū)的用戶表,會有用戶遷至另一座城市的情況。這些表也非常適合采用Merge-On-Read表型。

4.?表類型(Table Types) 4.1.?Copy On Write

在COW表中,只有數(shù)據(jù)文件/基本文件(.parquet),沒有增量日志文件(.log.*)。對每一個新批次寫入都將創(chuàng)建相應(yīng)數(shù)據(jù)文件的新版本(新的FileSlice),新版本文件包括舊版本文件的記錄以及來自傳入批次的記錄(全量最新)。

假設(shè)我們有 3 個文件組,其中包含如下數(shù)據(jù)文件。

我們進行一批新的寫入,在索引后,我們發(fā)現(xiàn)這些記錄與File group 1 和File group 2 匹配,然后有新的插入,我們將為其創(chuàng)建一個新的文件組(File group 4)。

因此data_file1 和 data_file2 都將創(chuàng)建更新的版本,data_file1 V2 是data_file1 V1 的內(nèi)容與data_file1 中傳入批次匹配記錄的記錄合并。由于在寫入期間進行合并,COW 會產(chǎn)生一些寫入延遲。但是COW 的優(yōu)勢在于它的簡單性,不需要其他表服務(wù)(如壓縮),也相對容易調(diào)試。

4.2.?Merge On Read

MOR表中,包含列存的基本文件(.parquet)和行存的增量日志文件(基于行的avro格式,.log.*)。顧名思義,MOR表的合并成本在讀取端。因此在寫入期間我們不會合并或創(chuàng)建較新的數(shù)據(jù)文件版本。標記/索引完成后,對于具有要更新記錄的現(xiàn)有數(shù)據(jù)文件,Hudi 創(chuàng)建增量日志文件并適當命名它們,以便它們都屬于一個文件組。

讀取端將實時合并基本文件及其各自的增量日志文件。每次的讀取延遲都比較高(因為查詢時進行合并),所以 Hudi 使用壓縮機制來將數(shù)據(jù)文件和日志文件合并在一起并創(chuàng)建更新版本的數(shù)據(jù)文件。

用戶可以選擇內(nèi)聯(lián)或異步模式運行壓縮。Hudi也提供了不同的壓縮策略供用戶選擇,最常用的一種是基于提交的數(shù)量。例如可以將壓縮的大增量日志配置為 4。這意味著在進行 4 次增量寫入后,將對數(shù)據(jù)文件進行壓縮并創(chuàng)建更新版本的數(shù)據(jù)文件。壓縮完成后,讀取端只需要讀取最新的數(shù)據(jù)文件,而不必關(guān)心舊版本文件。

MOR表的寫入行為,依據(jù) index 的不同會有細微的差別:

  • 對于 BloomFilter 這種無法對 log file 生成 index 的索引方案,對于 INSERT 消息仍然會寫 base file (parquet format),只有 UPDATE 消息會 append log 文件(因為 base file 已經(jīng)記錄了該 UPDATE 消息的 FileGroup ID)。
  • 對于可以對 log file 生成 index 的索引方案,例如 Flink writer 中基于 state 的索引,每次寫入都是 log format,并且會不斷追加和 roll over。
4.3.?COW與MOR的對比

CopyOnWrite

MergeOnRead

數(shù)據(jù)延遲

查詢延遲

Update(I/O) 更新成本

高(重寫整個Parquet文件)

低(追加到增量日志)

Parquet文件大小

低(更新成本I/O高)

較大(低更新成本)

寫放大

低(取決于壓縮策略)

5.?查詢類型(Query Types) 5.1.?Snapshot Queries

快照查詢,可以查詢指定commit/delta commit即時操作后表的最新快照。

在讀時合并(MOR)表的情況下,它通過即時合并最新文件片的基本文件和增量文件來提供近實時表(幾分鐘)。

對于寫時復制(COW),它可以替代現(xiàn)有的parquet表(或相同基本文件類型的表),同時提供upsert/delete和其他寫入方面的功能,可以理解為查詢最新版本的Parquet數(shù)據(jù)文件。

下圖是COW的快照查詢:

5.2.?Incremental Queries

增量查詢,可以查詢給定commit/delta commit即時操作以來新寫入的數(shù)據(jù)。有效的提供變更流來啟用增量數(shù)據(jù)管道。

5.3.?Read Optimized Queries

讀優(yōu)化查詢,可查看給定的commit/compact即時操作的表的最新快照。僅將最新文件片的基本/列文件暴露給查詢,并保證與非Hudi表相同的列查詢性能。

下圖是MOR表的快照查詢與讀優(yōu)化查詢的對比:

Read Optimized Queries是對Merge On Read表類型快照查詢的優(yōu)化。

Snapshot

Read Optimized

數(shù)據(jù)延遲

查詢延遲

高(合并列式基礎(chǔ)文件+行式增量日志文件)

低(原始列式基礎(chǔ)文件)

5.4.?不同表支持的查詢類型

6.?Compaction

(1)沒有 base file:走 copy on write insert 流程,直接 merge 所有的 log file 并寫 base file

(2)有 base file:走 copy on write upsert 流程,先讀 log file 建 index,再讀 base file,最后讀 log file 寫新的 base file

Flink 和 Spark streaming 的 writer 都可以 apply 異步的 compaction 策略,按照間隔 commits 數(shù)或者時間來觸發(fā) compaction 任務(wù),在獨立的 pipeline 中執(zhí)行。


注:其他Hudi相關(guān)文章鏈接由此進 ->Hudi文章匯總?


你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁名稱:Hudi(3):Hudi之基本概念-創(chuàng)新互聯(lián)
當前鏈接:http://www.bm7419.com/article36/dcdosg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)網(wǎng)站導航、定制網(wǎng)站、搜索引擎優(yōu)化、網(wǎng)站設(shè)計、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)