天天看點

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

背景

資料湖目前在國内外是比較熱的方案,MarketsandMarkets (

https://www.marketsandmarkets.com/Market-Reports/data-lakes-market-213787749.html

)市場調研顯示預計資料湖市場規模在2024年會從2019年的79億美金增長到201億美金。一些企業已經建構了自己的雲原生資料湖方案,有效解決了業務痛點;還有很多企業在建構或者計劃建構自己的資料湖。Gartner 2020年釋出的報告顯示(

https://www.gartner.com/smarterwithgartner/the-best-ways-to-organize-your-data-structures/

)目前已經有39%的使用者在使用資料湖,34%的使用者考慮在1年内使用資料湖。随着對象存儲等雲原生存儲技術的成熟,一開始大家會先把結構化、半結構化、圖檔、視訊等資料存儲在對象存儲中。當需要對這些資料進行分析時,會選擇比如Hadoop或者阿裡雲的雲原生資料湖分析服務DLA進行資料處理。對象存儲相比部署HDFS在分析性能上面有一定的劣勢,目前業界做了廣泛的探索和落地。

一、基于對象存儲分析面臨的挑戰

1、什麼是資料湖

Wikipedia上說資料湖是一類存儲資料自然/原始格式的系統或存儲,通常是對象塊或者檔案,包括原始系統所産生的原始資料拷貝以及為了各類任務而産生的轉換資料,包括來自于關系型資料庫中的結構化資料(行和列)、半結構化資料(如CSV、日志、XML、JSON)、非結構化資料(如email、文檔、PDF、圖像、音頻、視訊)。

從上面可以總結出資料湖具有以下特性:

  • 資料來源:原始資料、轉換資料
  • 資料類型:結構化資料、半結構化資料、非結構化資料、二進制
  • 資料湖存儲:可擴充的海量資料存儲服務

2、資料湖分析方案架構
聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

主要包括五個子產品:

  • 資料源:原始資料存儲子產品,包括結構化資料(Database等)、半結構化(File、日志等)、非結構化(音視訊等);
  • 資料內建:為了将資料統一到資料湖存儲及管理,目前資料內建主要分為三種形态外表關聯、ETL、異步中繼資料建構;
  • 資料湖存儲:目前業界資料湖存儲包括對象存儲以及自建HDFS。随着雲原生的演進,對象存儲在擴充性、成本、免運維有大量的優化,目前客戶更多的選擇雲原生對象存儲作為資料湖存儲底座,而不是自建HDFS。
  • 中繼資料管理:中繼資料管理,作為連接配接資料內建、存儲和分析引擎的總線;
  • 資料分析引擎:目前有豐富的分析引擎,比如Spark、Hadoop、Presto等。

3、面向對象存儲分析面臨的挑戰

對象存儲相比HDFS為了保證高擴充性,在中繼資料管理方面選擇的是扁平的方式;中繼資料管理沒有維護目錄結構,是以可以做到中繼資料服務的水準擴充,而不像HDFS的NameNode會有單點瓶頸。同時對象存儲相比HDFS可以做到免運維,按需進行存儲和讀取,建構完全的存儲計算分離架構。但是面向分析與計算也帶來了一些問題:

  • List慢:對象存儲按照目錄/進行list相比HDFS怎麼慢這麼多?
  • 請求次數過多:分析計算的時候怎麼對象存儲的請求次數費用比計算費用還要高?
  • Rename慢:Spark、Hadoop分析寫入資料怎麼一直卡在commit階段?
  • 讀取慢:1TB資料的分析,相比自建的HDFS叢集居然要慢這麼多!
  • ......

4、業界面向對象存儲分析優化現狀

上面這些是大家基于對象存儲建構資料湖分析方案遇到的典型問題。解決這些問題需要了解對象存儲相比傳統HDFS的架構差別進行針對性的優化。目前業界做了大量的探索和實踐:

  • JuiceFS:維護獨立的中繼資料服務,使用對象存儲作為存儲媒體。通過獨立中繼資料服務來提供高效的檔案管理語義,比如list、rename等。但是需要部署額外服務,所有的分析讀取對象存儲依賴該服務;
  • Hadoop:由于Hadoop、Spark寫入資料使用的是基于OutputCommitter兩階段送出協定,在OutputCommitter V1版本在commitTask以及commitJob會進行兩次rename。在對象存儲上面進行rename會進行對象的拷貝,成本很高。是以提出了OutputCommitter V2,該算法隻用做一次rename,但是在commitjob過程中斷會産生髒資料;
  • Alluxio:通過部署獨立的Cache服務,将遠端的對象存儲檔案Cache到本地,分析計算本地讀取資料加速;
  • HUDI:目前出現的HUDI、Delta Lake、Iceberg通過metadata的方式将dataset的檔案元資訊獨立存儲來規避list操作 ,同時提供和傳統資料庫類似的ACID以及讀寫隔離性;
  • 阿裡雲雲原生資料湖分析服務DLA:DLA服務在讀寫對象存儲OSS上面做了大量的優化,包括Rename優化、InputStream優化、Data Cache等。

二、DLA面向對象存儲OSS的架構優化

由于對象存儲面向分析場景具有上面的問題,DLA建構了統一的DLA FS層來解決對象存儲元資訊通路、Rename、讀取慢等問題。DLA FS同時支援DLA的Serverless Spark進行ETL讀寫、DLA Serverless Presto資料互動式查詢、Lakehouse入湖建倉資料的高效讀取等。面向對象存儲OSS的架構優化整體分為四層:

  • 資料湖存儲OSS:存儲結構化、半結構化、非結構化,以及通過DLA Lakehouse入湖建倉的HUDI格式;
  • DLA FS:統一解決面向對象存儲OSS的分析優化問題,包括Rename優化、Read Buffer、Data Cache、File List優化等;
  • 分析負載:DLA Serverless Spark主要讀取OSS中的資料ETL後再寫回OSS,Serverless Presto主要對OSS上面建倉的資料進行互動式查詢;
  • 業務場景:基于DLA的雙引擎Spark和Presto可以支援多種模式的業務場景。
聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

三、DLA FS面向對象存儲OSS優化技術解析

下面主要介紹DLA FS面向對象存儲OSS的優化技術:

1、Rename優化

在Hadoop生态中使用OutputCommitter接口來保證寫入過程的資料一緻性,它的原理類似于二階段送出協定。

開源Hadoop提供了Hadoop FileSystem的實作來讀寫OSS檔案,它預設使用的OutputCommitter的實作是FileOutputCommitter。為了資料一緻性,不讓使用者看到中間結果,在執行task時先把結果輸出到一個臨時工作目錄,所有task都确認輸出完成時,再由driver統一将臨時工作目錄rename到生産資料路徑中去。如下圖:

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

由于OSS相比HDFS它的Rename操作十分昂貴,是copy&delete操作,而HDFS則是NameNode上的一個中繼資料操作。在DLA的分析引擎繼續使用開源Hadoop的FileOutputCommitter性能很差,為了解決這個問題,我們決定在DLA FS中引入OSS Multipart Upload特性來優化寫入性能。

3.1 DLA FS支援Multipart Upload模式寫入OSS對象

阿裡雲OSS支援Multipart Upload功能,原理是把一個檔案分割成多個資料片并發上傳,上傳完成後,讓使用者自己選擇一個時機調用Multipart Upload的完成接口,将這些資料片合并成原來的檔案,以此來提高檔案寫入OSS的吞吐。由于Multipart Upload可以控制檔案對使用者可見的時機,是以我們可以利用它代替rename操作來優化DLA FS在OutputCommitter場景寫OSS時的性能。

基于Multipart Upload實作的OutputCommitter,整個算法流程如下圖:

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

利用OSS Multipart Upload,有以下幾個好處:

  • 寫入檔案不需要多次拷貝。可以看到,本來昂貴的rename操作已經不需要了,寫入檔案不需要copy&delete。另外相比于rename,OSS 的completeMultipartUpload接口是一個非常輕量的操作。
  • 出現資料不一緻的幾率更小。雖然如果一次要寫入多個檔案,此時進行completeMultipartUpload仍然不是原子性操作,但是相比于原先的rename會copy資料,他的時間視窗會縮短很多,出現資料不一緻的幾率會小很多,可以滿足絕大部分場景。
  • rename中的檔案元資訊相關操作不再需要。經過我們的統計,算法1中一個檔案的中繼資料操作可以從13次下降到6次,算法2則可以從8次下降到4次。

OSS Multipart Upload中控制使用者可見性的接口是CompleteMultipartUpload和abortMultipartUpload,這種接口的語義類似于commit/abort。Hadoop FileSystem标準接口沒有提供commit/abort這樣的語義。

為了解決這個問題,我們在DLA FS中引入Semi-Transaction層。

3.2 DLA FS引入Semi-Transaction層

前面有提到過,OutputCommitter類似于一個二階段送出協定,是以我們可以把這個過程抽象為一個分布式事務。可以了解為Driver開啟一個全局事務,各個Executor開啟各自的本地事務,當Driver收到所有本地事務完成的資訊之後,會送出這個全局事務。

基于這個抽象,我們引入了一個Semi-Transaction層(我們沒有實作所有的事務語義),其中定義了Transaction等接口。在這個抽象之下,我們把适配OSS Multipart Upload特性的一緻性保證機制封裝進去。另外我們還實作了OSSTransactionalOutputCommitter,它實作了OutputCommitter接口,上層的計算引擎比如Spark通過它和我們DLA FS的Semi-Transaction層互動,結構如下圖:

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

下面以DLA Serverless Spark的使用來說明DLA FS的OSSTransactionalOutputCommitter的大體流程:

  1. setupJob。Driver開啟一個GlobalTransaction,GlobalTransaction在初始化的時候會在OSS上建立一個隐藏的屬于這個GlobalTransaction的工作目錄,用來存放本job的檔案中繼資料。
  2. setupTask。Executor使用Driver序列化過來的GlobalTransaction生成LocalTransaction。并監聽檔案的寫入完成狀态。
  3. Executor寫檔案。檔案的中繼資料資訊會被LocalTransaction監聽到,并儲存到本地的RocksDB裡面,OSS遠端調用比較耗時,我們把中繼資料存儲到本地RocksDB上等到後續一次送出能夠減少遠端調用耗時。
  4. commitTask。當Executor調用LocalTransaction commit操作時,LocalTransaction會上傳這個Task它所相關的中繼資料到OSS對應的工作目錄中去,不再監聽檔案完成狀态。
  5. commitJob。Driver會調用GlobalTransaction的commit操作,全局事務會讀取工作目錄中的所有中繼資料中的待送出檔案清單,調用OSS completeMultipartUpload接口,讓所有檔案對使用者可見。

引入DLA FS的Semi-Transaction,有兩個好處:

  • 它不對任何計算引擎的接口有依賴,是以後面可以比較友善的移植到另外的一個計算引擎,通過适配可以将它所提供的實作給Presto或者其它計算引擎使用。
  • 可以在Transaction的語義下添加更多的實作。例如對于分區合并的這種場景,可以加入MVCC的特性,在合并資料的同時不影響線上對資料的使用。

2、InputStream優化

使用者回報OSS請求費用高,甚至超過了DLA費用(OSS請求費用=請求次數×每萬次請求的單價÷10000)。調查發現,是因為開源的OSSFileSystem在讀取資料的過程中,會按照512KB為一個機關進行預讀操作。例如,使用者如果順序讀一個1MB的檔案,會産生兩個對OSS的調用:第一個請求讀前512KB,第二個請求讀後面的512KB。這樣的實作就會造成讀大檔案時請求次數比較多,另外由于預讀的資料是緩存在記憶體裡面的,如果同時讀取的檔案比較多,也會給記憶體造成一些壓力。

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

是以,在DLA FS的實作中,我們去掉了預讀的操作,使用者調用hadoop的read時,底層會向OSS請求讀取從目前位置到檔案結尾整個範圍的資料,然後從OSS傳回的流中讀取使用者需要的資料并傳回。這樣如果使用者是順序讀取,下一個read調用就自然從同一個流中讀取資料,不需要發起新的調用,即使順序讀一個很大的檔案也隻需要一次對OSS的調用就可以完成。

另外,對于小的跳轉(seek)操作,DLA FS的實作是從流中讀取出要跳過的資料并丢棄,這樣也不需要産生新的調用,隻有大的跳轉才會關閉目前的流并且産生一個新的調用(這是因為大的跳轉讀取-丢棄會導緻seek的延時變大)。這樣的實作保證了DLA FS的優化在ORC/Parquet等檔案格式上面也會有減少調用次數的效果。

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

3、Data Cache加速

基于對象存儲OSS的存儲計算分離的架構,通過網絡從遠端存儲讀取資料仍然是一個代價較大的操作,往往會帶來性能的損耗。雲原生資料湖分析DLA FS中引入了本地緩存機制,将熱資料緩存在本地磁盤,拉近資料和計算的距離,減少從遠端讀取資料帶來的延時和IO限制,實作更小的查詢延時和更高的吞吐。

3.1 Local Cache架構

我們把緩存的處理邏輯封裝在DLA FS中。如果要讀取的資料存在于緩存中,會直接從本地緩存傳回,不需要從OSS拉取資料。如果資料不在緩存中,會直接從OSS讀取同時異步緩存到本地磁盤。

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

3.2 Data Cache命中率提高政策

這裡以DLA Serverless Presto來說明如何提高DLA FS的local Cache的命中率提高。Presto預設的split送出政策是NO_PREFERENCE,在這種政策下面,主要考慮的因素是worker的負載,是以某個split會被分到哪個worker上面很大程度上是随機的。在DLA Presto中,我們使用SOFT_AFFINITY送出政策。在送出Hive的split時,會通過計算split的hash值,盡可能将同一個split送出到同一個worker上面,進而提高Cache的命中率。

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

使用_SOFT_AFFINITY_政策時,split的送出政策是這樣的:

  1. 通過split的hash值确定split的首選worker和備選worker。
  2. 如果首選worker空閑,則送出到首選worker。
  3. 如果首選worker繁忙,則送出到備選worker。
  4. 如果備選worker也繁忙,則送出到最不繁忙的worker。

四、DLA FS帶來的價值

1、Rename優化在ETL寫入場景的效果

客戶在使用DLA過程中,通常使用DLA Serverless Spark做大規模資料的ETL。我們用TPC-H 100G資料集中的orders表進行寫入測試,建立一個以o_ordermonth字段為分區的orders_test表。在Spark中執行sql:"insert overwrite table `tpc_h_test`.`orders_test` select * from `tpc_h_test`.`orders`"。使用同樣的資源配置,使用的Spark版本一個為開源Spark,另外一個為DLA Serverless Spark,将它們的結果進行對比。

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

從圖中可以得出:

  • 這次優化對算法1和算法2都有比較大的提升。
  • 算法1和算法2開啟這個特性以後都會得到優化,但是算法1更明顯。這是由于算法1需要進行兩次rename,并且有一次rename是在driver上單點進行的;算法2是各executor進行分布式rename操作且隻要進行一次。
  • 在目前這個資料量下,算法1和算法2在開啟這個特性之後,差距沒有那麼明顯。兩種方式都不需要進行rename操作,隻不過是completeMultipart是否是在driver上單點執行(算法2我們的改造是completeMultipartUpload在commitTask的時候執行),大資料量可能仍會有比較大的影響。

2、InputStream優化在互動式場景的效果

DLA客戶會使用DLA的Serverless Presto對多種格式進行分析,比如Text、ORC、Parquet等。下面對比基于DLA FS以及社群OSSFS在1GB Text及ORC格式的通路請求次數。

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

1GB Text檔案分析的請求次數對比

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景
  • Text類調用次數降低為開源實作的1/10左右;
  • ORC格式調用次數降低為開源實作1/3左右;
  • 平均來看可以節省OSS調用費用60%到90%;

3、Data Cache在互動式場景的效果

我們針對社群版本prestodb和DLA做了性能對比測試。社群版本我們選擇了prestodb 0.228版本,并通過複制jar包以及修改配置的方式增加對oss資料源的支援。我們對DLA Presto CU版512核2048GB通社群版本叢集進行了對比。

測試的查詢我們選擇TPC-H 1TB資料測試集。由于TPC-H的大部分查詢并不是IO密集型的,是以我們隻從中挑選出符合如下兩個标準的查詢來做比較:

  1. 查詢中包含了對最大的表lineitem的掃描,這樣掃描的資料量足夠大,IO有可能成為瓶頸。
  2. 查詢中不涉及多個表的join操作,這樣就不會有大資料量參與計算,因而計算不會先于IO而成為瓶頸。

按照這兩個标準,我們選擇了對lineitem單個表進行查詢的Q1和Q6,以及lineitem和另一個表進行join操作的Q4、Q12、Q14、Q15、Q17、Q19和Q20。

可以看到Cache加速能管理在這幾個query都有明顯的效果。

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

五、雲原生資料湖最佳實踐

最佳實踐,以DLA為例子。DLA緻力于幫助客戶建構低成本、簡單易用、彈性的資料平台,比傳統Hadoop至少節約50%的成本。其中DLA Meta支援雲上15+種資料資料源(OSS、HDFS、DB、DW)的統一視圖,引入多租戶、中繼資料發現,追求邊際成本為0,免費提供使用。DLA Lakehouse基于Apache Hudi實作,主要目标是提供高效的湖倉,支援CDC及消息的增量寫入,目前這塊在加緊産品化中。DLA Serverless Presto是基于Apache PrestoDB研發的,主要是做聯邦互動式查詢與輕量級ETL。DLA支援Spark主要是為在湖上做大規模的ETL,并支援流計算、機器學習;比傳統自建Spark有着300%的成本效益提升,從ECS自建Spark或者Hive批處理遷移到DLA Spark可以節約50%的成本。基于DLA的一體化資料處理方案,可以支援BI報表、資料大屏、資料挖掘、機器學習、IOT分析、資料科學等多種業務場景。

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

歡迎大家進入我們的釘釘群一起交流讨論~

聚焦 | 資料湖分析如何面向對象存儲OSS進行優化?背景

繼續閱讀