雲原生背景介紹與思考
圖一是基于ECS底座的EMR架構,這是一套非常完整的開源大資料生态,也是近10年來每個數字化企業必不可少的開源大資料解決方案。主要分為以下幾層:
- ECS實體資源層,也就是Iaas層
-
資料接入層,例如實時的Kafka,離線的Sqoop
存儲層,包括HDFS和OSS,以及EMR自研的緩存加速JindoFS
- 計算引擎層,包括熟知的Spark,Presto、Flink等這些計算引擎
- 資料應用層,如阿裡自研的Dataworks、PAI以及開源的Zeppelin,Jupyter
每一層都有比較多的開源元件與之對應,這些層級組成了最經典的大資料解決方案,也就是EMR的架構。我們對此有以下思考:
- 是否能夠做到更好用的彈性,也就是客戶可以完全按照自己業務實際的峰值和低谷進行彈性擴容和縮容,保證速度足夠快,資源足夠充足
- 不考慮現有狀況,看未來幾年的發展方向,是否還需要支援所有的計算引擎和存儲引擎。這個問題也非常實際,一方面是客戶是否有能力維護這麼多的引擎,另一方面是是否某些場景下用一種通用的引擎即可解決所有問題。舉個例子說Hive和Mapreduce,誠然現有的一些客戶還在用Hive on Mapreduce,而且規模也确實不小,但是未來Spark會是一個很好的替代品。
- 存儲與計算分離架構,這是公認的未來大方向,存算分離提供了獨立的擴充性,客戶可以做到資料入湖,計算引擎按需擴容,這樣的解耦方式會得到更高的成本效益。

(圖1 基于ECS的開源大資料解決方案)
基于以上這些思考,我們考慮一下雲原生的這個概念,雲原生比較有前景的實作就是Kubernetes,是以有時候我們一提到雲原生,幾乎就等價于是Kubernetes。随着Kubernetes的概念越來越火,客戶也對該技術充滿了興趣,很多客戶已經把線上的業務搬到了Kubernetes之上。并且希望在這種類似作業系統上,建設一套統一的、完整的大資料基礎架構。是以我們總結為以下幾個特征:
- 希望能夠基于Kubernetes來包容線上服務、大資料、AI等基礎架構,做到運維體系統一化
- 存算分離架構,這個是大資料引擎可以在Kubernetes部署的前提,未來的趨勢也都在向這個方向走
- 通過Kubernetes的天生隔離特性,更好的實作離線與線上混部,達到降本增效目的
- Kubernetes生态提供了非常豐富的工具,我們可以省去很多時間搞基礎運維工作,進而可以專心來做業務
EMR計算引擎 on ACK
圖2是EMR計算引擎 on ACK的架構。ACK就是阿裡雲版本的Kubernetes,在相容社群版本的API同時,在本文中不會區分ACK和Kubernetes這兩個詞,可以認為代表同一個概念。
基于最開始的讨論,我們認為比較有希望的大資料批處理引擎是Spark和Presto,當然我們也會随着版本疊代逐漸的加入一些比較有前景的引擎。
EMR計算引擎提供以Kubernetes為底座的産品形态,本質上來說是基于CRD+Operator的組合,這也是雲原生最基本的哲學。我們針對元件進行分類,分為service元件和批處理元件,比如Hive Metastore就是service元件,Spark就是批處理元件。
圖中綠色部分是各種Operator,技術層面在開源的基礎上進行了多方面的改進,産品層面針對ACK底座進行了各方面的相容,能夠保證使用者在叢集中很友善的進行管控操作。右邊的部分,包括Log、監控、資料開發、ECM管控等元件,這裡主要是內建了阿裡雲的一些基礎設施。我們再來看下邊的部分:
- 引入了JindoFS作為OSS緩存加速層,做計算與存儲分離的架構
- 打通了現有EMR叢集的HDFS,友善客戶利用已有的EMR叢集資料
- 引入Shuffle Service來做Shuffle 資料的解耦,這也是EMR容器化差別于開源方案的比較大的亮點,之後會重點講到。
這裡明确一下,由于本身Presto是無狀态的MPP架構,在ACK中部署是相對容易的事情,本文主要讨論Spark on ACK的解決方案。
(圖2 計算引擎Kubernetes化)
Spark on Kubernetes的挑戰
整體看,Spark on Kubernetes面臨以下問題:
- 我個人認為最重要的,就是Shuffle的流程,按照目前的Shuffle方式,我們是沒辦法打開動态資源特性的。而且還需要挂載雲盤,雲盤面臨着Shuffle資料量的問題,挂的比較大會很浪費,挂的比較小又支援不了Shuffle Heavy的任務。
- 排程和隊列管理問題,排程性能的衡量名額是,要確定當大量作業同時啟動時,不應該有性能瓶頸。作業隊列這一概念對于大資料領域的同學應該非常熟悉,他提供了一種管理資源的視圖,有助于我們在隊列之間控制資源和共享資源。
- 讀寫資料湖相比較HDFS,在大量的Rename,List等場景下性能會有所下降,同時OSS帶寬也是一個不可避免的問題。
針對以上問題,我們分别來看下解決方案。
Spark on Kubernetes的解決方案
Remote Shuffle Service架構
Spark Shuffle的問題,我們設計了Shuffle 讀寫分離架構,稱為Remote Shuffle Service。首先探讨一下為什麼Kubernetes不希望挂盤呢,我們看一下可能的選項:
- 如果用是Docker的檔案系統,問題是顯而易見的,因為性能慢不說,容量也是極其有限,對于Shuffle過程是十分不友好的。
- 如果用Hostpath,熟悉Spark的同學應該知道,是不能夠啟動動态資源特性的,這個對于Spark資源是一個很大的浪費,而且如果考慮到後續遷移到Serverless K8s,那麼從架構上本身就是不支援Hostpath的。
- 如果是Executor挂雲盤的PV,同樣道理,也是不支援動态資源的,而且需要提前知道每個Executor的Shuffle資料量,挂的大比較浪費空間,挂的小Shuffle資料又不一定能夠容納下。
是以Remote Shuffle架構針對這一痛點、對現有的Shuffle機制有比較大的優化,圖3中間有非常多的控制流,我們不做具體的讨論,具體架構詳見文章《Serverless Spark的彈性利器 - EMR Shuffle Service》。主要來看資料流,對于Executor所有的Mapper和Reducer,也就是圖中的藍色部分是跑在了K8s容器裡,中間的架構是Remote Shuffle Service,藍色部分的Mapper将Shuffle資料遠端寫入service裡邊,消除了Executor的Task對于本地磁盤的依賴。Shuffle Service會對來自不同Mapper的同一partition的資料進行merge操作,然後寫入到分布式檔案系統中。等到Reduce階段,Reducer通過讀取順序的檔案,可以很好的提升性能。這套系統最主要的實作難點就是控制流的設計,還有各方面的容錯,資料去重,中繼資料管理等等工作。
簡而言之,我們總結為以下3點:
- Shuffle資料通過網絡寫出,中間資料計算與存儲分離架構
- DFS 2副本,消除Fetch Failed引起的重算,Shuffle Heavy作業更加穩定
- Reduce階段順序讀磁盤,避免現有版本的随機IO,大幅提升性能
雲原生計算引擎挑戰與解決方案
( 圖3 Remote Shuffle Service架構圖)
Remote Shuffle Service性能
我們在這裡展示一下關于性能的成績,圖4是Terasort的Benchmark成績。之是以選取Terasrot這種workload來測試,是因為他隻有3個stage,而且是一個大Shuffle的任務,大家可以非常有體感的看出關于Shuffle性能的變化。左邊圖,藍色是Shuffle Service版本的運作時間,橙色的是原版Shuffle的運作時間。我們觀察有2T,4T,10T的資料,可以看到随着資料量越來越大,Shuffle Service的優勢就越明顯。右圖觀察,作業的性能提升主要展現在了Reduce階段,可以看到10T的Reduce Read從1.6小時下降到了1小時。原因前邊已經解釋的很清楚了,熟悉spark shuffle機制的同學知道,原版的sort shuffle是M*N次的随機IO,在這個例子中,M是12000,N是8000,而Remote Shuffle就隻有N次順序IO,這個例子中是8000次,是以這是提升性能的根本所在。
(圖4 Remote Shuffle Service性能Benchmark)
其他方面的重點優化
這裡講一下EMR在其他方面做得優化
- 排程性能優化,我們解決了開源的Spark Operator的一些不足,對于Executor pod的很多配置Spark Operator把他做到了Webhook裡邊,這個對排程來說是十分不友好的,因為相當于在API Server上繞了一圈,實際測試下來性能損耗很大。我們把這些工作直接做到spark核心裡邊,這樣避免了這方面的排程性能瓶頸。然後從排程器層面上,我們保留了兩種選擇給客戶,包括ACK提供的Scheduler FrameworkV2實作方式和Yunicorn實作方式
- 讀寫OSS性能優化,我們這裡引入了JindoFS作為緩存,解決帶寬問題,同時EMR為OSS場景提供了Jindo Job Committer,專門優化了job commit的過程,大大減少了Rename和List等耗時操作
- 針對Spark本身,EMR積累了多年的技術優勢,也在TPCDS官方測試中,取得了很好的成績,包括Spark性能、穩定性,還有Delta lake的優化也都有內建進來。
- 我們提供了一站式的管控,包括Notebook作業開發,監控日志報警等服務,還繼承了NameSpace的ResourceQuota等等。
總體來說,EMR版本的Spark on ACK,無論在架構上、性能上、穩定性上、易用性方面都有着很大的提升。
Spark雲原生後續展望
從我的視角來觀察,Spark雲原生容器化後續的方向,一方面是達到運維一體化,另一方面主要希望做到更好的成本效益。我們總結為以下幾點:
- 可以将Kubernetes計算資源分為固定叢集和Serverless叢集的混合架構,固定叢集主要是一些包年包月、資源使用率很高的叢集,Serverless是做到按需彈性。
- 可以通過排程算法,靈活的把一些SLA不高的任務排程到Spot執行個體上,就是支援搶占式ECI容器,這樣可以進一步降低成本。
- 由于提供了Remote Shuffle Service叢集,充分讓Spark在架構上解耦本地盤,隻要Executor空閑就可以銷毀。配合上OSS提供的存算分離,必定是後續的主流方向。
- 對于排程能力,這方面需要特别的增強,做到能夠讓客戶感受不到性能瓶頸,短時間内排程起來大量的作業。同時對于作業隊列管理方面,希望做到更強的資源控制和資源共享。
雲原生計算引擎挑戰與解決方案
(圖5 Spark on Kubernetes混合架構)
大資料雲原生的落地是十分具有挑戰性的,EMR團隊也會和社群和合作夥伴一起打造技術和生态,我們的願景是:
- 存算分離,按需擴充
- 極緻彈性,随用随得
- 運維閉環,高成本效益
更多資料湖技術相關的文章請點選:
阿裡雲重磅釋出雲原生資料湖體系更多資料湖相關資訊交流請加入阿裡巴巴資料湖技術釘釘群