掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
本次分享主要是針對Apache Hudi 0.11.0新版本新特性進行深度解讀,主要介紹4個方面的內(nèi)容:

站在用戶的角度思考問題,與客戶深入溝通,找到鹽池網(wǎng)站設(shè)計與鹽池網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站設(shè)計、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、國際域名空間、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋鹽池地區(qū)。
首先和大家分享下多級索引,接下來我們將從三個方面介紹它。第一是為什么我們引入多級索引multi model index,第二多級索引的設(shè)計以及實踐,最后將介紹如何利用多級索引,極大提升讀寫性能。
在介紹多級索引之前,我們先看看索引是什么?索引是數(shù)據(jù)庫系統(tǒng)中常用的查詢加速技術(shù)。通過構(gòu)建索引就可以利用生成的元數(shù)據(jù)metadata快速定位查詢所需數(shù)據(jù)的位置,這樣可以減少甚至避免從文件系統(tǒng)中掃描或者讀取不必要的數(shù)據(jù),減少IO的開銷,大大提升查詢效率。我們可以類比圖書館以及教科書中的索引,這些都是通過利用提前生成好的metadata來快速找到想要查找的信息。
其實在Apache Hudi的湖倉一體的架構(gòu)中已經(jīng)提供了特有的索引支持,這里我們可以看一個例子。其中我們用的一種索引可以快速定位到我們所需要更新或者刪除的記錄所在的文件組。如下圖所示:
如果沒有index的情況下,對于所有的更新以及刪除的記錄,我們需要和所有的文件進行merge,這樣開銷會非常大。如果使用了索引,讀寫開銷會極大地降低,可以提高查詢這個位置的效率。
在Hudi中我們默認(rèn)開啟了基于bloom filter的索引。這些bloom filter是存儲在數(shù)據(jù)文件的footer中。作為一個單獨的存在,它可以被用到索引的流程過程中。
那我們?yōu)槭裁催€要在Hudi中引用多級索引?其實索引的主要目的就是剛剛提到的提升數(shù)據(jù)查詢的速度,那么就需要存儲metadata。而對于TB、EB級別表中的metadata,它們的量級會很大。通常的做法是把它們存儲于單獨的數(shù)據(jù)塊block或者是數(shù)據(jù)文件中。而我們在實測的過程中,遇到了讀寫瓶頸。同時,在維護metadata的過程中,它需要實時的和數(shù)據(jù)表進行同步。這樣的管理十分復(fù)雜,因為要保證transaction,如果我們要在Hudi中引用新的索引開發(fā)周期會很長。
為了解決上述的問題,我們在湖倉一體的存儲架構(gòu)中引入了多級索引,是首次在類似的架構(gòu)中引入統(tǒng)一平臺、多元化、高性能的索引。我們的目標(biāo)是支持所有計算及查詢引擎來提升讀寫性能,甚至未來如果出現(xiàn)新的引擎,也是可以進行兼容的。
接下來我們介紹一些在多級索引設(shè)計中所需要的需求。
我們分別來看一下是如何實現(xiàn)的。
首先是可拓展的元數(shù)據(jù),我們采用了和已有數(shù)據(jù)庫類似的設(shè)計,那就是在內(nèi)部構(gòu)建一個元數(shù)據(jù)表meta table。對于Hudi table來說,我們利用的是Hudi的mor表來存儲這些數(shù)據(jù)。mor表的優(yōu)勢是可以很快地進行數(shù)據(jù)的更新與刪除。同時,Hudi表也是Serverless的,它不會依賴任何計算及內(nèi)存資源。在這個表里我們針對不同的索引是建立獨立的分區(qū)的。在這樣的情況下,不同的index可以完成獨立的管理以及自動化的管理。我們在使用mor表的另一個優(yōu)點是可以支持任意的索引大小。從mb級別到gb級別再到tb級別。針對獨立的分支,我們可以引入新的作用類型,就只需要建立新的分區(qū)。在構(gòu)建可拓展的元數(shù)據(jù)的時候,需要索引的一個初始化。我們提高了兩種方式的初始化。一種是同步,同步是在寫入表的過程中,在最后commit之前會做一個index的步驟。而第二種方式是異步。異步創(chuàng)建索引是hudi首次引入的,保證了concurrent writer 不受影響。下面是異步創(chuàng)建索引的流程圖:
接下來介紹多級索引所帶來的主要的讀寫性能提升。
在云存儲中我們發(fā)現(xiàn)大部分情況下,如果對于大型表的上千分區(qū)以及百萬級的數(shù)據(jù)文件做listing,會造成讀寫瓶頸。這主要是因為云存儲的設(shè)計所導(dǎo)致的。如果我們利用metadata table中的files來做分區(qū)。這個分區(qū)里提供了這個數(shù)據(jù)表里所有的file。相比于云軟件系統(tǒng)有2-20倍的提升。如下圖:
Data Skipping 技術(shù)是利用列統(tǒng)計數(shù)據(jù)來對所需要的這個數(shù)據(jù)文件做file pruning (文件裁剪),列統(tǒng)計數(shù)據(jù)常見的列統(tǒng)計數(shù)據(jù)包括取最大值、最小值、數(shù)量、大小等。Data Skipping 的作用就是通過這些統(tǒng)計數(shù)據(jù)來排除掉不需要讀的文件,這樣可以極大的提高查詢速度。我們在這個multi model index 的metadata 中構(gòu)建了column_stats分區(qū),這個分區(qū)里的每條記錄包含了這個Hudi表里所對應(yīng)文件的列統(tǒng)計數(shù)據(jù)。每個Record key是由列名稱、分區(qū)名稱和文件名稱組成。通過這種排列格式,可以快速定位所需的column stats。查詢復(fù)雜度是基于查詢列所需要的列的數(shù)量,通常這個數(shù)量是5到10個。對于大寬表來說,這樣可以極大地提升這個效果。在實際測試中,云上Hudi大寬表的“定向”查詢速度有10x-30x的提升。大幅減少了對無關(guān)數(shù)據(jù)文件的掃描和讀取,提高了I/O效率。如下圖:
接下來再講Hudi在Spark SQL方面的改進。
Spark SQL改進Delete Operation。
在t1時刻分別往mor表cow表中分別插入a,b,c三條數(shù)據(jù)。這樣會在mor表中生成base file 文件和log file文件(下圖中簡化了示意圖)。在cow表中只會生產(chǎn)base file 文件。t2時刻同時刪除mor表和cow表中 b的數(shù)據(jù)。mor表操作是刪除log file b的block是t2時刻的數(shù)據(jù)。而cow表中的操作是復(fù)制一份base file b保存到內(nèi)存中,刪除b數(shù)據(jù)之后會形成一個新版本的綠色的方框中的數(shù)據(jù)文件。如下圖:
我們?yōu)槭裁匆獙崿F(xiàn)Time travel?從api層面,如果我們要寫一個查詢,需要設(shè)置不同的df,構(gòu)造不同的operation,然后來查詢這個動作。但是引用time travel的這個語句以后,一是可以在spark sql中直接使用,二是sql語句更容易去解釋這樣的一個行為和動作?,F(xiàn)在可以通過timestamp as of語法支持時間旅行查詢,但僅限Spark 3.2+。語法如下:select * from hudi_tbl timestamp as of '20210728141108100'
①SQL Travel-場景1:查詢多版本數(shù)據(jù)
如下圖,我們在10:10分提交了insert和update語句,我們想要查10:05分版本的數(shù)據(jù),通過下面的sql是可以實現(xiàn)的。
select * from test_hudi timestamp as of 20220512100510000 (10:05)
select * from test_hudi timestamp as of 20220512101030000 (10:10)
②Travel-場景2: 數(shù)據(jù)還原修復(fù)
注意:如果這個表用了 truncate清空的話,這種時間戳方式查詢恢復(fù)就不行了。
Call Command產(chǎn)生的一個背景是spark sql除了ddl、dql和dml之外的操作,我們想解決這三種操作之外的一些新功能的操作。那么在引入Call Command之前是沒辦法操作的。我們對比了一下傳統(tǒng)數(shù)據(jù)庫里面的存儲過程,類似地在spark這一塊實現(xiàn)了一個command動作,然后對應(yīng)實現(xiàn)了一個procedure的功能。
首先是在hudi一側(cè)為call command生成了一個通用的語法,不依賴于spark的版本,可以對所有spark版本適用。然后生成了一個HoodieProcedure的類,使用CallProcedureHoodieCommand類調(diào)用動作。
Call Command命令在設(shè)計時主要有四個方面的功能。一是支持歸檔、提交、回滾和創(chuàng)建還原點的快照動作。二是可以進行原數(shù)據(jù)管理。三是對運維表進行數(shù)據(jù)導(dǎo)入導(dǎo)出、Boostrap、修復(fù)表、升級/降級等操作。四是優(yōu)化表動作,如Compaction、Clustering、Clean等。
Call Command的參數(shù)有三類。一是可以使用不定式的參數(shù)(鍵值對)作為它的入?yún)?shù)。二是可以按照參數(shù)的位置進行入?yún)?。三是混合參?shù)。以下是傳參的具體語法:
①CALL Command-快照管理的相應(yīng)的命令
call rollback_to_instant('test_hudi_table',20220511224632307')
②CALL Command-Clustering
可以設(shè)置Clustering的類型:
set hoodie.layout.optimize.strategy=linear /z-order/hilbert
常用命令:
call run_clustering(table => 'test_hudi_table',order => 'ts')
call show_clustering(table=>'test_hudi_table')
通過這些clustering的動作,在查詢的時候性能能達到10-20倍的提升。
③CALL Command-Compact(小文件合并)(目前只支持mor表)
Data file和Delta log file 合并會重新生成一個新的文件。
命令:call run_compaction(table=>'test_hudi_table',op=> instant
最后,介紹Flink集成改進方面的內(nèi)容。主要有以下幾點:
綠色是目前已經(jīng)實現(xiàn)的操作,紅色是待實現(xiàn)的操作??梢酝ㄟ^ApI實現(xiàn)或者是Flink Sql實現(xiàn)。
FlinkHoodieCatalog在三個方面有比較好的作用:
為什么要集成改進Bucket Index?這個是字節(jié)的同學(xué)貢獻的一個功能。他們在他們的生產(chǎn)場景里面,在34tb的數(shù)據(jù)量在5000億的記錄寫入的情況下,Bloom Filter Index 通過Record key去找File ID 的這樣的一個動作的性能會下降得很快。為了解決Bloom Filter Index的假陽性,他們引入了Bucket Index。
通過key的哈希值定位到File Group,提升了實時導(dǎo)入的性能。如下圖所示:
從Flink輸入了5條數(shù)據(jù),然后通過一定的哈希策略將混合的Bucket Index進行關(guān)聯(lián),通過拿到FileGroupId寫入文件。
Bucket分布優(yōu)化主要有:Bucket Pruning、Bucket Aggregate、Bucket Join等。如下圖所示:
參數(shù):hoodie.index.type 值:BUCKET
參數(shù):hoodie.bucket.index.num.buckets 值:48(256MB)
建議單個桶的大小控制在3GB左右。
最后,我們來講其他功能和提升。
我們在使用mor表做快照查詢的時候,log文件會被讀取,然后和base文件進行合并。在之前的版本中,當(dāng)你做快照查詢的時候,整條log文件記錄會被讀出來。這個版本我們做了優(yōu)化,使用了內(nèi)置的標(biāo)準(zhǔn)Payload來讀取。例如:OverwriteWithLatestAvroPayload。我們會針對這個做了優(yōu)化,只把必要的列讀出來,這樣就會極大的減少內(nèi)存和壓縮解碼帶來的CPU的消耗。其實是對于非常寬的上千列的表來說,效果會非常明細。
在這個版本中,我們針對Spark 3.1、Spark 3.2版本增加了schema功能的演進。如果啟用 set hoodie.schema.on.read.enable=true以后,我們可以對表列和對表進行一系列的操作。列的變更(增加、刪除、重命名、修改位置、修改屬性),表的變更(重命名、修改屬性) 等。
保存點和恢復(fù)可以用call command做這些操作。新版本引進了mor表,用Hudi CLI設(shè)定保存點和執(zhí)行恢復(fù)或者call command來手動設(shè)置保存點。保存點之后的數(shù)據(jù)將會被刪除。
hoodie.write.commit.callback.pulsar.topic
hoodie.write.commit.callback.pulsar.broker.service.url

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流