聚焦 | 数据湖分析如何面向对象存储OSS进行优化?
簡介: 最佳實踐,以DLA為例子。DLA致力于幫助客戶構(gòu)建低成本、簡單易用、彈性的數(shù)據(jù)平臺,比傳統(tǒng)Hadoop至少節(jié)約50%的成本。其中DLA Meta支持云上15+種數(shù)據(jù)數(shù)據(jù)源(OSS、HDFS、DB、DW)的統(tǒng)一視圖,引入多租戶、元數(shù)據(jù)發(fā)現(xiàn),追求邊際成本為0,免費提供使用。DLA Lakehouse基于Apache Hudi實現(xiàn),主要目標(biāo)是提供高效的湖倉,支持CDC及消息的增量寫入,目前這塊在加緊產(chǎn)品化中。DLA Serverless Presto是基于Apache PrestoDB研發(fā)的,主要是做聯(lián)邦交互式查詢與輕量級ETL。
背景
?
數(shù)據(jù)湖當(dāng)前在國內(nèi)外是比較熱的方案,MarketsandMarkets (https://www.marketsandmarkets.com/Market-Reports/data-lakes-market-213787749.html)市場調(diào)研顯示預(yù)計數(shù)據(jù)湖市場規(guī)模在2024年會從2019年的79億美金增長到201億美金。一些企業(yè)已經(jīng)構(gòu)建了自己的云原生數(shù)據(jù)湖方案,有效解決了業(yè)務(wù)痛點;還有很多企業(yè)在構(gòu)建或者計劃構(gòu)建自己的數(shù)據(jù)湖。Gartner 2020年發(fā)布的報告顯示(https://www.gartner.com/smarterwithgartner/the-best-ways-to-organize-your-data-structures/)目前已經(jīng)有39%的用戶在使用數(shù)據(jù)湖,34%的用戶考慮在1年內(nèi)使用數(shù)據(jù)湖。隨著對象存儲等云原生存儲技術(shù)的成熟,一開始大家會先把結(jié)構(gòu)化、半結(jié)構(gòu)化、圖片、視頻等數(shù)據(jù)存儲在對象存儲中。當(dāng)需要對這些數(shù)據(jù)進行分析時,會選擇比如Hadoop或者阿里云的云原生數(shù)據(jù)湖分析服務(wù)DLA進行數(shù)據(jù)處理。對象存儲相比部署HDFS在分析性能上面有一定的劣勢,目前業(yè)界做了廣泛的探索和落地。
?
一、基于對象存儲分析面臨的挑戰(zhàn)
1、什么是數(shù)據(jù)湖
Wikipedia上說數(shù)據(jù)湖是一類存儲數(shù)據(jù)自然/原始格式的系統(tǒng)或存儲,通常是對象塊或者文件,包括原始系統(tǒng)所產(chǎn)生的原始數(shù)據(jù)拷貝以及為了各類任務(wù)而產(chǎn)生的轉(zhuǎn)換數(shù)據(jù),包括來自于關(guān)系型數(shù)據(jù)庫中的結(jié)構(gòu)化數(shù)據(jù)(行和列)、半結(jié)構(gòu)化數(shù)據(jù)(如CSV、日志、XML、JSON)、非結(jié)構(gòu)化數(shù)據(jù)(如email、文檔、PDF、圖像、音頻、視頻)。
?
從上面可以總結(jié)出數(shù)據(jù)湖具有以下特性:
- 數(shù)據(jù)來源:原始數(shù)據(jù)、轉(zhuǎn)換數(shù)據(jù)
- 數(shù)據(jù)類型:結(jié)構(gòu)化數(shù)據(jù)、半結(jié)構(gòu)化數(shù)據(jù)、非結(jié)構(gòu)化數(shù)據(jù)、二進制
- 數(shù)據(jù)湖存儲:可擴展的海量數(shù)據(jù)存儲服務(wù)
2、數(shù)據(jù)湖分析方案架構(gòu)
主要包括五個模塊:
- 數(shù)據(jù)源:原始數(shù)據(jù)存儲模塊,包括結(jié)構(gòu)化數(shù)據(jù)(Database等)、半結(jié)構(gòu)化(File、日志等)、非結(jié)構(gòu)化(音視頻等);
- 數(shù)據(jù)集成:為了將數(shù)據(jù)統(tǒng)一到數(shù)據(jù)湖存儲及管理,目前數(shù)據(jù)集成主要分為三種形態(tài)外表關(guān)聯(lián)、ETL、異步元數(shù)據(jù)構(gòu)建;
- 數(shù)據(jù)湖存儲:目前業(yè)界數(shù)據(jù)湖存儲包括對象存儲以及自建HDFS。隨著云原生的演進,對象存儲在擴展性、成本、免運維有大量的優(yōu)化,目前客戶更多的選擇云原生對象存儲作為數(shù)據(jù)湖存儲底座,而不是自建HDFS。
- 元數(shù)據(jù)管理:元數(shù)據(jù)管理,作為連接數(shù)據(jù)集成、存儲和分析引擎的總線;
- 數(shù)據(jù)分析引擎:目前有豐富的分析引擎,比如Spark、Hadoop、Presto等。
?
3、面向?qū)ο蟠鎯Ψ治雒媾R的挑戰(zhàn)
?
對象存儲相比HDFS為了保證高擴展性,在元數(shù)據(jù)管理方面選擇的是扁平的方式;元數(shù)據(jù)管理沒有維護目錄結(jié)構(gòu),因此可以做到元數(shù)據(jù)服務(wù)的水平擴展,而不像HDFS的NameNode會有單點瓶頸。同時對象存儲相比HDFS可以做到免運維,按需進行存儲和讀取,構(gòu)建完全的存儲計算分離架構(gòu)。但是面向分析與計算也帶來了一些問題:
?
- List慢:對象存儲按照目錄/進行l(wèi)ist相比HDFS怎么慢這么多?
- 請求次數(shù)過多:分析計算的時候怎么對象存儲的請求次數(shù)費用比計算費用還要高?
- Rename慢:Spark、Hadoop分析寫入數(shù)據(jù)怎么一直卡在commit階段?
- 讀取慢:1TB數(shù)據(jù)的分析,相比自建的HDFS集群居然要慢這么多!
- ......
4、業(yè)界面向?qū)ο蟠鎯Ψ治鰞?yōu)化現(xiàn)狀
上面這些是大家基于對象存儲構(gòu)建數(shù)據(jù)湖分析方案遇到的典型問題。解決這些問題需要理解對象存儲相比傳統(tǒng)HDFS的架構(gòu)區(qū)別進行針對性的優(yōu)化。目前業(yè)界做了大量的探索和實踐:
?
- JuiceFS:維護獨立的元數(shù)據(jù)服務(wù),使用對象存儲作為存儲介質(zhì)。通過獨立元數(shù)據(jù)服務(wù)來提供高效的文件管理語義,比如list、rename等。但是需要部署額外服務(wù),所有的分析讀取對象存儲依賴該服務(wù);
- Hadoop:由于Hadoop、Spark寫入數(shù)據(jù)使用的是基于OutputCommitter兩階段提交協(xié)議,在OutputCommitter V1版本在commitTask以及commitJob會進行兩次rename。在對象存儲上面進行rename會進行對象的拷貝,成本很高。因此提出了OutputCommitter V2,該算法只用做一次rename,但是在commitjob過程中斷會產(chǎn)生臟數(shù)據(jù);
- Alluxio:通過部署獨立的Cache服務(wù),將遠(yuǎn)程的對象存儲文件Cache到本地,分析計算本地讀取數(shù)據(jù)加速;
- HUDI:當(dāng)前出現(xiàn)的HUDI、Delta Lake、Iceberg通過metadata的方式將dataset的文件元信息獨立存儲來規(guī)避list操作 ,同時提供和傳統(tǒng)數(shù)據(jù)庫類似的ACID以及讀寫隔離性;
- 阿里云云原生數(shù)據(jù)湖分析服務(wù)DLA:DLA服務(wù)在讀寫對象存儲OSS上面做了大量的優(yōu)化,包括Rename優(yōu)化、InputStream優(yōu)化、Data Cache等。
?
二、DLA面向?qū)ο蟠鎯SS的架構(gòu)優(yōu)化
?
由于對象存儲面向分析場景具有上面的問題,DLA構(gòu)建了統(tǒng)一的DLA FS層來解決對象存儲元信息訪問、Rename、讀取慢等問題。DLA FS同時支持DLA的Serverless Spark進行ETL讀寫、DLA Serverless Presto數(shù)據(jù)交互式查詢、Lakehouse入湖建倉數(shù)據(jù)的高效讀取等。面向?qū)ο蟠鎯SS的架構(gòu)優(yōu)化整體分為四層:
?
- 數(shù)據(jù)湖存儲OSS:存儲結(jié)構(gòu)化、半結(jié)構(gòu)化、非結(jié)構(gòu)化,以及通過DLA Lakehouse入湖建倉的HUDI格式;
- DLA FS:統(tǒng)一解決面向?qū)ο蟠鎯SS的分析優(yōu)化問題,包括Rename優(yōu)化、Read Buffer、Data Cache、File List優(yōu)化等;
- 分析負(fù)載:DLA Serverless Spark主要讀取OSS中的數(shù)據(jù)ETL后再寫回OSS,Serverless Presto主要對OSS上面建倉的數(shù)據(jù)進行交互式查詢;
- 業(yè)務(wù)場景:基于DLA的雙引擎Spark和Presto可以支持多種模式的業(yè)務(wù)場景。
三、DLA FS面向?qū)ο蟠鎯SS優(yōu)化技術(shù)解析
?
下面主要介紹DLA FS面向?qū)ο蟠鎯SS的優(yōu)化技術(shù):
?
1、Rename優(yōu)化
在Hadoop生態(tài)中使用OutputCommitter接口來保證寫入過程的數(shù)據(jù)一致性,它的原理類似于二階段提交協(xié)議。
?
開源Hadoop提供了Hadoop FileSystem的實現(xiàn)來讀寫OSS文件,它默認(rèn)使用的OutputCommitter的實現(xiàn)是FileOutputCommitter。為了數(shù)據(jù)一致性,不讓用戶看到中間結(jié)果,在執(zhí)行task時先把結(jié)果輸出到一個臨時工作目錄,所有task都確認(rèn)輸出完成時,再由driver統(tǒng)一將臨時工作目錄rename到生產(chǎn)數(shù)據(jù)路徑中去。如下圖:
由于OSS相比HDFS它的Rename操作十分昂貴,是copy&delete操作,而HDFS則是NameNode上的一個元數(shù)據(jù)操作。在DLA的分析引擎繼續(xù)使用開源Hadoop的FileOutputCommitter性能很差,為了解決這個問題,我們決定在DLA FS中引入OSS Multipart Upload特性來優(yōu)化寫入性能。
?
3.1 DLA FS支持Multipart Upload模式寫入OSS對象
?
阿里云OSS支持Multipart Upload功能,原理是把一個文件分割成多個數(shù)據(jù)片并發(fā)上傳,上傳完成后,讓用戶自己選擇一個時機調(diào)用Multipart Upload的完成接口,將這些數(shù)據(jù)片合并成原來的文件,以此來提高文件寫入OSS的吞吐。由于Multipart Upload可以控制文件對用戶可見的時機,所以我們可以利用它代替rename操作來優(yōu)化DLA FS在OutputCommitter場景寫OSS時的性能。
?
基于Multipart Upload實現(xiàn)的OutputCommitter,整個算法流程如下圖:
利用OSS Multipart Upload,有以下幾個好處:
?
- 寫入文件不需要多次拷貝。可以看到,本來昂貴的rename操作已經(jīng)不需要了,寫入文件不需要copy&delete。另外相比于rename,OSS 的completeMultipartUpload接口是一個非常輕量的操作。
- 出現(xiàn)數(shù)據(jù)不一致的幾率更小。雖然如果一次要寫入多個文件,此時進行completeMultipartUpload仍然不是原子性操作,但是相比于原先的rename會copy數(shù)據(jù),他的時間窗口會縮短很多,出現(xiàn)數(shù)據(jù)不一致的幾率會小很多,可以滿足絕大部分場景。
- rename中的文件元信息相關(guān)操作不再需要。經(jīng)過我們的統(tǒng)計,算法1中一個文件的元數(shù)據(jù)操作可以從13次下降到6次,算法2則可以從8次下降到4次。
?
OSS Multipart Upload中控制用戶可見性的接口是CompleteMultipartUpload和abortMultipartUpload,這種接口的語義類似于commit/abort。Hadoop FileSystem標(biāo)準(zhǔn)接口沒有提供commit/abort這樣的語義。
?
為了解決這個問題,我們在DLA FS中引入Semi-Transaction層。
?
3.2 DLA FS引入Semi-Transaction層
?
前面有提到過,OutputCommitter類似于一個二階段提交協(xié)議,因此我們可以把這個過程抽象為一個分布式事務(wù)。可以理解為Driver開啟一個全局事務(wù),各個Executor開啟各自的本地事務(wù),當(dāng)Driver收到所有本地事務(wù)完成的信息之后,會提交這個全局事務(wù)。
?
基于這個抽象,我們引入了一個Semi-Transaction層(我們沒有實現(xiàn)所有的事務(wù)語義),其中定義了Transaction等接口。在這個抽象之下,我們把適配OSS Multipart Upload特性的一致性保證機制封裝進去。另外我們還實現(xiàn)了OSSTransactionalOutputCommitter,它實現(xiàn)了OutputCommitter接口,上層的計算引擎比如Spark通過它和我們DLA FS的Semi-Transaction層交互,結(jié)構(gòu)如下圖:
下面以DLA Serverless Spark的使用來說明DLA FS的OSSTransactionalOutputCommitter的大體流程:
?
?
引入DLA FS的Semi-Transaction,有兩個好處:
- 它不對任何計算引擎的接口有依賴,因此后面可以比較方便的移植到另外的一個計算引擎,通過適配可以將它所提供的實現(xiàn)給Presto或者其它計算引擎使用。
- 可以在Transaction的語義下添加更多的實現(xiàn)。例如對于分區(qū)合并的這種場景,可以加入MVCC的特性,在合并數(shù)據(jù)的同時不影響線上對數(shù)據(jù)的使用。
?
2、InputStream優(yōu)化
用戶反饋OSS請求費用高,甚至超過了DLA費用(OSS請求費用=請求次數(shù)×每萬次請求的單價÷10000)。調(diào)查發(fā)現(xiàn),是因為開源的OSSFileSystem在讀取數(shù)據(jù)的過程中,會按照512KB為一個單位進行預(yù)讀操作。例如,用戶如果順序讀一個1MB的文件,會產(chǎn)生兩個對OSS的調(diào)用:第一個請求讀前512KB,第二個請求讀后面的512KB。這樣的實現(xiàn)就會造成讀大文件時請求次數(shù)比較多,另外由于預(yù)讀的數(shù)據(jù)是緩存在內(nèi)存里面的,如果同時讀取的文件比較多,也會給內(nèi)存造成一些壓力。
因此,在DLA FS的實現(xiàn)中,我們?nèi)サ袅祟A(yù)讀的操作,用戶調(diào)用hadoop的read時,底層會向OSS請求讀取從當(dāng)前位置到文件結(jié)尾整個范圍的數(shù)據(jù),然后從OSS返回的流中讀取用戶需要的數(shù)據(jù)并返回。這樣如果用戶是順序讀取,下一個read調(diào)用就自然從同一個流中讀取數(shù)據(jù),不需要發(fā)起新的調(diào)用,即使順序讀一個很大的文件也只需要一次對OSS的調(diào)用就可以完成。
?
另外,對于小的跳轉(zhuǎn)(seek)操作,DLA FS的實現(xiàn)是從流中讀取出要跳過的數(shù)據(jù)并丟棄,這樣也不需要產(chǎn)生新的調(diào)用,只有大的跳轉(zhuǎn)才會關(guān)閉當(dāng)前的流并且產(chǎn)生一個新的調(diào)用(這是因為大的跳轉(zhuǎn)讀取-丟棄會導(dǎo)致seek的延時變大)。這樣的實現(xiàn)保證了DLA FS的優(yōu)化在ORC/Parquet等文件格式上面也會有減少調(diào)用次數(shù)的效果。
3、Data Cache加速
基于對象存儲OSS的存儲計算分離的架構(gòu),通過網(wǎng)絡(luò)從遠(yuǎn)端存儲讀取數(shù)據(jù)仍然是一個代價較大的操作,往往會帶來性能的損耗。云原生數(shù)據(jù)湖分析DLA FS中引入了本地緩存機制,將熱數(shù)據(jù)緩存在本地磁盤,拉近數(shù)據(jù)和計算的距離,減少從遠(yuǎn)端讀取數(shù)據(jù)帶來的延時和IO限制,實現(xiàn)更小的查詢延時和更高的吞吐。
?
3.1 Local Cache架構(gòu)
我們把緩存的處理邏輯封裝在DLA FS中。如果要讀取的數(shù)據(jù)存在于緩存中,會直接從本地緩存返回,不需要從OSS拉取數(shù)據(jù)。如果數(shù)據(jù)不在緩存中,會直接從OSS讀取同時異步緩存到本地磁盤。
?
3.2 Data Cache命中率提高策略
這里以DLA Serverless Presto來說明如何提高DLA FS的local Cache的命中率提高。Presto默認(rèn)的split提交策略是NO_PREFERENCE,在這種策略下面,主要考慮的因素是worker的負(fù)載,因此某個split會被分到哪個worker上面很大程度上是隨機的。在DLA Presto中,我們使用SOFT_AFFINITY提交策略。在提交Hive的split時,會通過計算split的hash值,盡可能將同一個split提交到同一個worker上面,從而提高Cache的命中率。
使用_SOFT_AFFINITY_策略時,split的提交策略是這樣的:
四、DLA FS帶來的價值
1、Rename優(yōu)化在ETL寫入場景的效果
客戶在使用DLA過程中,通常使用DLA Serverless Spark做大規(guī)模數(shù)據(jù)的ETL。我們用TPC-H 100G數(shù)據(jù)集中的orders表進行寫入測試,新建一個以o_ordermonth字段為分區(qū)的orders_test表。在Spark中執(zhí)行sql:"insert overwrite table `tpc_h_test`.`orders_test` select * from `tpc_h_test`.`orders`"。使用同樣的資源配置,使用的Spark版本一個為開源Spark,另外一個為DLA Serverless Spark,將它們的結(jié)果進行對比。
從圖中可以得出:
- 這次優(yōu)化對算法1和算法2都有比較大的提升。
- 算法1和算法2開啟這個特性以后都會得到優(yōu)化,但是算法1更明顯。這是由于算法1需要進行兩次rename,并且有一次rename是在driver上單點進行的;算法2是各executor進行分布式rename操作且只要進行一次。
- 在當(dāng)前這個數(shù)據(jù)量下,算法1和算法2在開啟這個特性之后,差距沒有那么明顯。兩種方式都不需要進行rename操作,只不過是completeMultipart是否是在driver上單點執(zhí)行(算法2我們的改造是completeMultipartUpload在commitTask的時候執(zhí)行),大數(shù)據(jù)量可能仍會有比較大的影響。
?
2、InputStream優(yōu)化在交互式場景的效果
DLA客戶會使用DLA的Serverless Presto對多種格式進行分析,比如Text、ORC、Parquet等。下面對比基于DLA FS以及社區(qū)OSSFS在1GB Text及ORC格式的訪問請求次數(shù)。
1GB Text文件分析的請求次數(shù)對比
- Text類調(diào)用次數(shù)降低為開源實現(xiàn)的1/10左右;
- ORC格式調(diào)用次數(shù)降低為開源實現(xiàn)1/3左右;
- 平均來看可以節(jié)省OSS調(diào)用費用60%到90%;
?
3、Data Cache在交互式場景的效果
我們針對社區(qū)版本prestodb和DLA做了性能對比測試。社區(qū)版本我們選擇了prestodb 0.228版本,并通過復(fù)制jar包以及修改配置的方式增加對oss數(shù)據(jù)源的支持。我們對DLA Presto CU版512核2048GB通社區(qū)版本集群進行了對比。
?
測試的查詢我們選擇TPC-H 1TB數(shù)據(jù)測試集。由于TPC-H的大部分查詢并不是IO密集型的,所以我們只從中挑選出符合如下兩個標(biāo)準(zhǔn)的查詢來做比較:
?
?
按照這兩個標(biāo)準(zhǔn),我們選擇了對lineitem單個表進行查詢的Q1和Q6,以及l(fā)ineitem和另一個表進行join操作的Q4、Q12、Q14、Q15、Q17、Q19和Q20。
?
可以看到Cache加速能管理在這幾個query都有明顯的效果。
?
五、云原生數(shù)據(jù)湖最佳實踐
?
最佳實踐,以DLA為例子。DLA致力于幫助客戶構(gòu)建低成本、簡單易用、彈性的數(shù)據(jù)平臺,比傳統(tǒng)Hadoop至少節(jié)約50%的成本。其中DLA Meta支持云上15+種數(shù)據(jù)數(shù)據(jù)源(OSS、HDFS、DB、DW)的統(tǒng)一視圖,引入多租戶、元數(shù)據(jù)發(fā)現(xiàn),追求邊際成本為0,免費提供使用。DLA Lakehouse基于Apache Hudi實現(xiàn),主要目標(biāo)是提供高效的湖倉,支持CDC及消息的增量寫入,目前這塊在加緊產(chǎn)品化中。DLA Serverless Presto是基于Apache PrestoDB研發(fā)的,主要是做聯(lián)邦交互式查詢與輕量級ETL。DLA支持Spark主要是為在湖上做大規(guī)模的ETL,并支持流計算、機器學(xué)習(xí);比傳統(tǒng)自建Spark有著300%的性價比提升,從ECS自建Spark或者Hive批處理遷移到DLA Spark可以節(jié)約50%的成本。基于DLA的一體化數(shù)據(jù)處理方案,可以支持BI報表、數(shù)據(jù)大屏、數(shù)據(jù)挖掘、機器學(xué)習(xí)、IOT分析、數(shù)據(jù)科學(xué)等多種業(yè)務(wù)場景。
原文鏈接
本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的聚焦 | 数据湖分析如何面向对象存储OSS进行优化?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python C扩展的引用计数问题探讨
- 下一篇: 殷浩详解DDD:领域层设计规范