MaxCompute技術人背後的故事:從ApacheORC到AliORC

2019大數據技術公開課第一季《技術人生專訪》來襲,本季將帶領開發者們探討大數據技術,分享不一樣國家的工做體驗。本文整理自阿里巴巴計算平臺事業部高級技術專家吳剛的專訪,將爲你們介紹Apache ORC開源項目、主流的開源列存格式ORC和Parquet的區別以及MaxCompute選擇ORC的緣由。此外,吳還將分享他是如何一步步成爲Apache開源項目的Committer和PMC的。算法

如下內容根據演講視頻以及PPT整理而成。性能優化

我的簡介

吳剛,阿里巴巴計算平臺事業部高級技術專家 ,Apache頂級開源項目ORC的PMC ,目前主要負責MaxCompute平臺存儲線 相關工做。以前就任於Uber總部,從事Spark和Hive等相關工做。網絡

1、Apache ORC項目介紹以及阿里巴巴對於ORC項目的貢獻

Apache ORC Projectapp

正如Apache ORC項目官網所介紹的,Apache ORC是Hadoop生態系統中最快、最小的列式存儲文件格式。Apache ORC主打的三個特性包括支持ACID,也就是支持事務,支持內置索引以及支持各類複雜類型。運維

ORC Adopter異步

Apache ORC有不少的採用者,好比你們所熟知的Spark、Presto、Hive、Hadoop等開源軟件。此外,在2017年,阿里巴巴MaxCompute技術團隊也開始參與到Apache ORC項目的工做中,並將ORC做爲MaxCompute內置的文件存儲格式之一。oop

Timeline性能

Apache ORC項目的大體發展歷程以下圖所示。在2013年初的時候,Hortonworks開始在來替代RCFile文件格式 ,通過了兩個版本的迭代,ORC孵化成爲了Apache頂級項目,而且順利地從Hive中脫離出來成爲一個單獨的項目。在2017年1月,阿里雲MaxCompute團隊開始向ORC社區持續地貢獻代碼,而且使得ORC成爲MaxCompute內置的文件格式之一。
學習

Contribution from Alibaba測試

阿里巴巴MaxCompute技術團隊爲Apache ORC項目作出了大量貢獻,好比研發了一個完整的C++的ORC Writer,修復了一些極爲重要的Bug,而且大大提高了ORC的性能。阿里巴巴MaxCompute技術團隊總共向Apache ORC項目提交了30多個Patch,總計1萬5千多行代碼,而且目前阿里仍然在持續地向ORC貢獻代碼。阿里巴巴的技術團隊中共有3個ORC項目貢獻者,1個PMC和1個Committer。在2017年的Hadoop Summit上,ORC也專門用一頁PPT來點名表揚阿里巴巴對於ORC項目的貢獻。

2、阿里雲MaxCompute爲什麼選擇ORC?

Row-based VS. Column-based

對於文件存儲而言,有兩種主流的方式,即按行存儲以及按列存儲。所謂按行存儲就是把每一行數據依次存儲在一塊兒,先存儲第一行的數據再存儲第二行的數據,以此類推。而所謂按列存儲就是把表中的數據按照列存儲在一塊兒,先存儲第一列的數據,再存儲第二列的數據。而在大數據場景之下,每每只須要獲取部分列的數據,那麼使用列存就能夠只讀取少許數據,這樣能夠節省大量磁盤和網絡I/O的消耗。此外,由於相同列的數據屬性很是類似,冗餘度很是高,列式存儲能夠增大數據壓縮率,進而大大節省磁盤空間。所以,MaxCompute最終選擇了列存。

A Quick Look at ORC

ORC在類型系統上的建模是一個樹形結構,對於一些諸如Struct這樣的複雜類型會有一個或者多個孩子節點,而Map類型有兩個孩子節點,即key和value,List類型就只有一個孩子節點,其餘的普通類型則就是一個葉子節點。以下圖所示,左側的表結構就可以被形象地轉化成右側的樹型結構,簡單而且直觀。

ORC主要有兩個優化指標,其一 爲查詢速度。ORC將文件切分紅大小相近的塊,在塊內部使用列式存儲,也就是將相同列的數據存儲到一塊兒。針對於這些數據,ORC提供輕量的索引支持,包括數據塊的最小值、最大值、計數和空值等,基於這些統計信息,能夠很是方便地過濾掉不須要讀取的數據,以此減小數據的傳輸。此外,ORC還支持列裁剪 (Column Projection),若是查詢中只須要讀取部分列,那麼Reader只須要返回所需的列數據,進一步減少了須要讀取的數據量。

ORC的第二個優化指標就是存儲效率。ORC採用了通用的壓縮算法,好比開源的zStandard、zlib、snappy、LZO等來提升文件壓縮率。同時,ORC也採用了輕量的編碼算法,好比run-length encoding、dictionary等。

How about Apache Parquet

在開源軟件領域中,與 Apache ORC 對標的就是Apache Parquet。Parquet是由 Cloudera 和 Twitter 共同開發的,其靈感來源於 Google 發表的Dremel的論文。Parquet 的思想和 ORC 很是相近,也是將文件拆分紅大小相近的塊,並在塊裏面使用列式存儲,而且對於開源系統的支持與 ORC 也相差無幾,也可以支持 Spark、Presto 等,而且也使用了列式存儲和通用的壓縮以及編碼算法,也可以提供輕量級索引以及統計信息。

相比ORC,Parquet主要有兩點不一樣。第一點就是Parquet可以更好地支持嵌套類型,Parquet可以經過使用definition和repetition levels方式來標識複雜類型的層數等信息,不過這樣的設計卻很是複雜,就連Google的論文中也使用整整一頁來介紹這個算法,但在實際中,大部分數據並無使用很是深的嵌套,這像是一個「殺雞用牛刀」的方法。此外,Parquet的編碼類型比ORC也更多一些,其支持plain、bit-packing以及浮點數等編碼方式,因此Parquet在某些數據類型的壓縮率上比ORC更高。

Benchmark: ORC VS Parquet

  • Datasets

基於Github日誌數據和紐約市出租車數據這兩個開源數據集,Hadoop開源社區進行了ORC和Parquet
的性能對比 ,並獲得了一些統計數據。

  • Storage Cost

下圖比較了ORC、Parquet以及JSON等文件存儲方式的性能效率。在Taxi Size的這張表中能夠看出,Parquet和ORC存儲性能很是相近。

下圖展現了Github項目數據集下的存儲效率比較,從中能夠看出ORC比Parquet的壓縮率更高一些,壓縮後數據量變得更小。

所以,綜上所述,在存儲效率方面,ORC和Parquet壓縮效率不相上下,在部分數據上ORC優點更大。

  • Full Table Scan

以下所示列出了ORC和Parquet對於兩個數據集的讀表效率對比狀況。整體而言,ORC都比Parquet要更快一些。基於以上比較,MaxCompute最終選擇了ORC,由於其不只設計更爲簡單,而且讀表性能更高。

AliORC = Alibaba ORC

經過上述Benchmark的比較,MaxCompute基於對於性能的考量選擇了ORC。而在其餘方面,相比於Parquet,ORC也有一些優點,好比前面提到的設計更爲簡單、代碼質量更佳、語言無關性 、可以高效地支持多種開源項目。 而且因爲ORC研發團隊相對更爲集中,創始人對於項目具備較強的掌控力,所以阿里巴巴提出的任何需求和想法均可以得到快速響應和比較有力的支持,進而成爲社區的領導者。

3、AliORC和開源ORC有何不一樣?

AliORC is More Than Apache ORC

AliORC是基於開源Apache ORC的深度優化的文件格式。AliORC的首要目標仍是和開源的ORC徹底兼容,這樣才能更加方便於用戶的使用。AliORC主要從兩個方面對於開源的ORC進行了優化,一方面,AliORC提供了更多的擴展特性,好比對於Clustered Index和C++ Arrow的支持以及謂詞下推等。另外一方面,AliORC還進行了性能優化,實現了異步預讀、I/O模式管理以及自適應字典編碼等。

AliORC Optimization

  • Async Prefetch

這裏選取幾個AliORC對於開源的ORC優化的具體特性進行分享。首先就是Async Prefetch (異步預讀)。傳統讀文件的方式通常是從底層文件系統先拿到原始數據,而後進行解壓和解碼,這兩步操做分別是I/O密集型和CPU密集型任務,而且二者沒有任何並行性,所以就加長了總體的端到端時間,但實際上並沒有必要,而且形成了資源的浪費。AliORC實現了從文件系統讀數據和解壓解碼操做的並行處理,這樣就將全部的讀盤操做變成了異步的,也就是提早將讀取數據的請求所有發送出去,當真正須要數據的時候就去檢查以前的異步請求是否返回了數據,若是數據已經返回,則能夠當即進行解壓和解碼操做,而不須要等待讀盤,這樣就能夠極大地提升並行度,並下降讀取文件的所需時間。

以下圖所示的就是打開了異步預讀優化先後的性能對比。開啓異步預讀以前,讀取一個文件須要14秒,而在打開異步預讀以後則只須要3秒,讀取速度提高了數倍。由於將全部的讀請求都變成了異步的,當異步請求返回較慢時仍是會變成同步請求。從右側餅圖能夠看出,實際狀況下80%以上的異步請求都是有效的。

  • Small I/O Elimination

AliORC的第二個優化點就是對於小I/O的消除。在ORC文件中,不一樣列的文件大小是徹底不一樣的,可是每次讀盤都是以列爲單位進行數據讀取的。這樣一來,對於數據量比較小的列而言,讀取時的網絡I/O開銷很是大。爲了消除這些小的I/O開銷,AliORC在Writer部分針對不一樣列的數據量進行了排序,在reader端將小數據量的列放在一塊兒造成一個大I/O塊,這樣不只減小了小I/O數量,還大大地提高了並行度。

以下圖所示的是AliORC打開Small I/O Elimination先後的對比狀況。藍色部分表示的就是打開Small I/O Elimination以前的I/O分佈狀況,橙色的部分則是表示打開以後的I/O分佈狀況。能夠看到,打開Small I/O Elimination以前,小於64K的I/O有26個,而在打開以後,小於64K的I/O爲零,所以Small I/O Elimination的優化效果仍是很是顯著的。

  • Memory Management for streams in each column

AliORC的第三個優化點就是在內存管理 。在開源版本的ORC實現中,Writer的每列數據都使用了一個很大的Buffer去保存壓縮後的數據,默認大小爲1M,其目的在於 Buffer設置得越大,壓縮率越高。可是正如前面所說的,不一樣列的數據量不一樣,某些列根本用不到1M大小的Buffer,所以就會形成極大的內存浪費。避免內存浪費的簡單方法就是在一開始的時候只給很小的數據塊做爲Buffer,而且按需分配,若是須要寫的數據更多,那麼就經過相似C++std::vector的resize 方式提供更大的數據塊。本來實現方式中,resize一次就須要進行一次O(N)的操做,將原始數據從老的Buffer拷貝到新的Buffer中去,這樣對於性能而言是不可接受的。所以,AliORC開發了新的內存管理結構,分配64K的Block,可是Block與Block之間不是連續的,這雖然會形成不少代碼的改動,可是這一改動倒是值得的。由於在不少場景下,原來的resize方式須要消耗不少內存,有可能形成內存耗盡,進而致使任務沒法完成,而新的方式能夠在這種場景下大大下降內存的峯值,效果很是明顯。

  • Seek Read

AliORC的第四個優化點就是Seek Read方面的優化。這部分解釋略微複雜,所以這裏以一個例子進行歸納。Seek Read原來的問題在於壓縮塊比較大,每一個壓縮塊中包含不少個Block。在圖中,每一萬行數據叫作一個Row Group。在Seek Read的場景下,可能會Seek Read到文件中間的某一段,其多是包含在某一個壓縮塊中間的,好比圖中第7個Row Group被包含在第2個Block中。常規Seek的操做就是先跳轉第2個Block的頭部,而後進行解壓,將第7個Row Group以前的數據先解壓出來,再真正地跳轉到第7個Row Group處。可是圖中綠色的部分數據並非咱們所須要的,所以這一段的數據量就被白白解壓了,浪費掉不少計算資源。所以,AliORC的想法就是就是【在寫文件的時候】將壓縮塊Block和Row Group的邊界進行對齊,所以Seek到任何的Row Group都不須要進行沒必要要的解壓操做。

如圖所示的是進行Seek Read優化先後的效果對比。藍色部分是優化以前的狀況,橙色部分表明優化以後的狀況。能夠發現,有了對於Seek Read的優化,解壓所需的時間和數據量都下降了5倍左右。

  • Adapting Dictionary Encoding

字典編碼就是針對重複度比較高的字段首先整理出來一個字典,而後使用字典中的序號來代替原來的數據進行編碼,至關於將字符串類型數據的編碼轉化成整型數據的編碼,這樣能夠大大減小數據量。可是ORC編碼存在一些問題,首先,不是全部的字符串都適合字典編碼,而在原來的數據中,每一列都是默認打開字典編碼的,而當文件結束時再判斷列是否適合字典編碼,若是不適合,再回退到非字典編碼。因爲回退操做至關於須要重寫字符串類型數據,所以開銷會很是大。AliORC所作的優化就是經過一個自適應的算法提前決定某一列是否須要使用字典編碼,這樣就能夠節省不少的計算資源。開源的ORC中經過標準庫中的std::unordered_map來實現字典編碼,可是它的實現方式並不適合MaxCompute的數據,而Google開源的dense_hash_map庫能夠帶來10%的寫性能提高,所以AliORC採用了這種實現方式。最後,開源的ORC標準中要求對於字典類型進行排序,但其實是沒有任何須要的,剔除掉該限制可使得Writer端的性能提升3%。

  • Range Alignment for Range Partition

這部分主要是對於Range Partition的優化。以下圖右側的DDL所示,想要將一張表按照某些列進行RANGE CLUSTERED並對這些列的數據進行排序,好比將這些數據存儲到4個桶中,分別存儲0到一、2到三、4到8以及9到無窮大的數據。這樣作的優點在於,在具體實現過程當中,每一個桶都使用了一個ORC文件,在ORC文件尾部存儲了一個相似於B+Tree的索引。當須要進行查詢的時候,若是查詢的Filter和Range Key相關,就能夠直接利用該索引來排除不須要讀取的數據,進而大大減小所須要獲取的數據量。

對於Range Partition而言,AliORC具備一個很強大的功能,叫作Range對齊。這裏解釋一下,假設須要Join兩張Range Partition的表,它們的Join Key就是Range Partition Key。以下圖所示,表A有三個Range,表B有兩個Range。在普通表的狀況下,這兩個表進行Join會產生大量的Shuffle,須要將相同的數據Shuffle到同一個Worker上進行Join操做,而Join操做又是很是消耗內存和CPU資源的。而有了Range Partition以後,就能夠將Range的信息進行對齊,將A表的三個桶和B表的兩個桶進行對齊,產生以下圖所示的三個藍色區間。以後就能夠肯定藍色區間以外的數據是不可能產生Join結果,所以Worker根本不須要讀取那些數據。

完成優化以後,每一個Worker只須要打開藍色區域的數據進行Join操做便可。這樣就可使得Join操做可以在本地Worker中完成,而不須要進行Shuffle,進而大大下降了數據傳輸量,提升了端到端的效率。

4、AliORC爲用戶帶來的價值

以下圖所示的是在阿里巴巴內部測試中AliORC和開源的C++版本ORC以及Java版本ORC的讀取時間比較。從圖中能夠看出AliORC的讀取速度比開源ORC要快一倍。

截止2019年5月,在阿里巴巴內部也迭代了3個版本,從下圖能夠看出,每一個版本之間也有接近30%的性能提高,而且還在持續優化當中。目前,AliORC還處於內部使用階段,還沒有在公有云上進行發佈,後續也會將AliORC開放出來,讓你們共享技術紅利。

5、淺談阿里雲MaxCompute相比同類產品的優點

首先,MaxCompute是開箱即用的,也就是說用戶無需額外的設置,直接啓動MaxCompute服務就能夠在其上運行任務了。而使用Hive或者Spark等開源軟件可能會存在不少Bug,而對於問題的排查也異常困難,開源社區的修復週期也很是漫長。當用戶使用MaxCompute時遇到問題,可以很快地獲得反饋而且完成修復。

其次,MaxCompute的使用成本比較低,能夠實現按量付費。而使用Hive或者Spark每每須要自建數據中心,這樣的作法很是繁瑣,建設數據中心不只須要支付機器成本,還須要本身進行運維。

再次,使用開源的Hive或者Spark,對於技術人員而言,門檻也比較高。由於須要招募一些很是瞭解Hive和Spark的工程師才能進行維護。而公司本身開發的一些特性每每會和開源版本產生衝突,每次都須要對於衝突進行解決。而當開源版本的軟件每次升級以後,就須要將新版本代碼下載下來以後再將本身的開發的特性從新加進去,過程異常繁瑣。而使用MaxCompute以後,這些工做無需用戶關心,阿里巴巴會幫助客戶處理這些問題。

對於穩定性而言,MaxCompute作的也很是好。其抗住了歷年雙11的流量洪峯,而直接使用Hadoop生態系統很難支持很大的體量的任務,每每須要各類深度定製優化。

MaxCompute另一個優點在於性能,MaxCompute是第一個跑過100TB數據量的TPCx-BB的Benchmark的平臺,這是Spark至今沒有達到的成就。

此外,開源產品每每不夠重視中國市場。Cloudera、Databricks等公司的主要目標客戶仍是在美國,每每更傾向於根據美國客戶需求進行開發,而對於中國市場的支持不夠好。MaxCompute則緊跟中國客戶的須要,同時也更加適合中國市場。

最後一點就是隻有在MaxCompute裏面才能使用AliORC這樣的文件格式,這也是獨有的優點。

總結而言,相比於開源軟件,MaxCompute具備需求響應更加及時、成本更低、技術門檻更低、穩定性更高、性能更好、更加適合中國市場等特性。

6、爲什麼選擇加入MaxCompute團隊

從我的角度而言,我更加看好大數據領域。雖然對於一項技術而言,黃金期每每只有10年,而對於大數據技術而言,已經經歷了10年,但我相信大數據技術並不會衰落。尤爲是在人工智能技術的加持下,大數據技術仍然有不少須要解決的問題,其技術仍然沒有達到的完美。此外,阿里的MaxCompute團隊更是人才輩出,北京、杭州、西雅圖等團隊都具備強大的技術實力,可以學習到不少。最後一點,對於開源大數據產品而言,基本上都是國外的天下,而MaxCompute是徹底國產自研的平臺,加入MaxCompute團隊讓本身很是驕傲,可以有機會爲國產軟件盡一份力量。

7、如何走上大數據技術之路的

我走上大數據技術這條路也是機緣巧合的,以前在學校裏面所學習的內容與大數據徹底沒有關係,第一份工做也是視頻編碼相關的工做,後來在Uber轉向大數據相關的崗位。在進入Uber以前,Hadoop組還處於組建的早期,基本上尚未人真正使用Hadoop,你們都是本身搭建一些服務來運行任務。當進入Uber的Hadoop組以後,跟着團隊從0到1地學習了Scala、Spark等,從最開始瞭解如何使用Spark到了解Spark源碼,而後慢慢地搭建起大數據平臺,接觸大數據領域。進入阿里巴巴以後,經過MaxCompute可以從需求、設計、開發、測試以及最後的優化等所有階段來了解大數據產品,這也是比較寶貴的經歷。

8、在阿里巴巴美國辦公室的工做體驗

在阿里的美國部門其實和在阿里國內的部門差異並不大,可能在西雅圖的辦公室人數並非不少,可是「麻雀雖小,五臟俱全」。西雅圖辦公室各個BU的成員都很是優秀,可以和不一樣技術方向的同事碰撞出不一樣的思惟火花。而且在阿里巴巴的美國辦公室,每一年有不少對外交流的機會,也能夠組織不少開源的分享。

9、如何成爲第一位華人ORC的PMC

這實際上是由於MaxCompute團隊須要ORC這款產品,而當時開源的C++版本的ORC只有Reader,卻沒有Writer,所以就須要自行開發C++版本的ORC的Writer。當MaxCompute團隊完成以後就但願集合開源的力量將C++版本的ORC的Writer作好,所以將代碼貢獻回了開源社區,而且獲得了開源社區的承認。基於這些工做量,ORC的開源社區給了MaxCompute團隊兩個Committer名額。成爲Committer以後,責任也就更大了,不只本身須要寫代碼,還須要和社區一塊兒成長,review其餘成員的代碼,討論短時間和長期的問題。ORC社區對於本身和MaxCompute團隊的工做較爲承認,所以授予了PMC的職位。對我的而言,ORC開源的工做也表明了阿里巴巴對於開源的態度,不只須要在數量上足夠多,還須要保證質量足夠好。

10、寄語

只要你對於開源感興趣並樂於持續地貢獻,不管擁有什麼樣的背景和基礎,全部的付出最終都會被承認。



本文做者:KB小祕書

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索