作者:邵賽賽
轉載自公眾號:數據湖技術
原文鏈接:https://mp.weixin.qq.com/s/dgLrh2GqnMu1rRqYpCtjoA
前言
在ABC (AI, BigData, Cloud)時代,傳統的大數據解決方案和廠商 (Cloudera, Hortonworks) 略顯頹勢,而云廠商 (AWS, Azure, GCP) 和雲原生解決方案 (Databricks Cloud, Snowflake, ElasticSearch等) 則愈加迸發出活力。在這個雲原生的時代擁抱雲變成了不二之選,那麼對於Spark[1]來說它是如何在雲原生時代積極擁抱雲的呢?
背景
10多年前,Google的3篇論文拉開了大數據時代的大幕,這3篇論文不僅從理論上詳盡地闡述了分佈式大數據的經典算法,更從工程上解決了普通商業硬件的分佈式架構之道,同時也定義了未來多年內的普通商業硬件,尤其是大數據服務器的設計架構。
當時一臺典型的大數據服務器通常包括一路或兩路CPU,核數從十幾核到幾十核不等 (Hyper Threading);幾十G的內存;多塊SATA或SAS HDD硬盤。
受限於當時硬件的能力,軟件上的設計需要考慮到硬件的行為從而能更好地利用到硬件的性能:
•移動代碼而非移動數據:MapReduce框架在實現時非常強調的一點是移動代碼而非移動數據,因為代碼的大小相比於數據是小很多的,在網絡帶寬較小的時代移動數據會帶來巨大的開銷,相反將代碼放到數據所在節點去執行能帶來顯著的提升。
•數據和計算共存:正是由於移動代碼而非移動數據的設計思路而形成了數據和計算共存的架構。一個典型的Hadoop集群通常會把數據集群HDFS和計算集群MapReduce (YARN) 部署在一起提高數據本地性 (Data Locality)。
•帶寬優先設計:大數據應用由於處理的數據量巨大通常需要較長的處理時間,在這樣的前提下在MapReduce設計之初就有了這樣一條假設:大數據任務通常對於響應的要求較低。因此在MapReduce設計中無論是任務分發還是數據傳輸優先考慮的是帶寬而非延遲。
•充分利用多盤優勢,避免隨機讀寫:HDD由於機械結構的限制其順序讀寫的吞吐量一般在100~200MB左右,而隨機讀寫的性能則會更差。相較於CPU的處理能力有量級的差距。為了匹配速度差,通常會使用多塊HDD磁盤來並行化和分散IO,提高整體IO吞吐量。同時在IO設計的時候也會盡量把隨機IO轉換成順序IO以提高吞吐量 (Sort based shuffle write/read就是一個典型的例子)。
當然還有其他許多的優化考量點不在這羅列了。重要的是在這10多年間,從軟件架構到硬件性能,從服務器設計到數據中心架構都有了巨大的變化,這其中包括:
•容器化。隨著docker的誕生,容器化技術在後臺服務領域迅速推廣開來,容器化不僅能帶來devops的便捷性,同時也能更好地隔離資源。而Kubernetes的誕生,則將容器化應用和容器化調度推到了一個新的高度。
•存儲計算分離。隨著網絡帶寬的提升和異構集群技術的發展,存儲計算分離被再度提出了,尤其是在公有云上存儲計算分離已成為常態,如何更好地適應存儲計算分離變得尤為重要。
•更快的存儲設備。更快的存儲設備近些年來不斷推出,如SSD,PMEM等,這些新的存儲設備不僅有更高的速率,而且大大優化了隨機讀寫的性能。
•顯著提升的網絡帶寬。近10年中網絡帶寬得到了顯著的提升,從最早的1Gbps,到現在主流的10Gbps,25Gbps乃至40Gbps,100Gbps。同時RDMA,DPDK的應用也越來越廣泛。
這樣的變化對於現有的大數據軟件架構帶來了極大的挑戰,原先的設計在新的硬件和架構中變得不再有意義:
1.存儲計算分離使得我們所恪守的數據本地性不再有意義,所有的數據不再是本地的了,更快的網絡抹平了本地性帶來的優勢。
2.更高的網絡帶寬和更低的延遲使得我們不必再以帶寬優先來設計網絡傳輸,更低的延遲變得更有意義。
3.更快的存儲設備,更好的隨機讀寫性能使得我們所做的對於順序讀寫的優化 (歸併排序) 變成了額外的負擔。
因此面向新的硬件和架構,面向雲原生的時代,大數據軟件的設計必須進行相應的調整和優化以發揮更好的性能。Spark作為當前最為主流的分佈式計算框架,它又是如何在雲原生時代做出相應的改變的呢?
Spark演化的方向
容器化
容器化由於其優異的devops能力、資源隔離、統一調度等特性,在微服務和後臺架構中有廣泛的應用,但是在大數據、Hadoop領域容器化卻沒有廣泛的採用,這其中制約大數據容器化的問題主要有哪些呢?
1.容器化調度和大數據應用所恪守的數據本地性相背離,會帶來一定的性能問題。
2.大數據應用對於系統性能、尤其是IO性能要求較高,而容器化有一定的性能開銷。
3.更為重要的是大數據系統架構之時容器化技術、容器化調度尚未興起,在融入容器化技術中需要與原有架構做較大的調整。
當然容器化技術的調度也是日新月異的,上面所列的問題在新的版本中可能已不復存在。既然有這樣那樣的問題,那為什麼大數據還需要容器化呢?
•首先在企業devops流程中,docker技術已是事實上的標準,同時前後端技術也已經全面docker化了,統一企業devops流程,將大數據應用docker化是一個自然的過程。
•其次容器化調度框架Kubernetes已成為企業數據中心統一的DCOS,所有的前後臺部署都使用k8s統一進行調度。但大數據存儲和計算遊離在容器化調度之外,額外部署管理增加了管理負擔和資源開銷。
•容器化技術所提供的資源隔離對於大數據應用來說有很大的意義。大數據應用通常對於資源的需求是激進的,如果沒有很好的資源管理和隔離機制,會造成應用的互相影響,降低應用的穩定性,因此有效的資源隔離是非常必要的。
在這樣的背景下,容器化並支持容器化調度是現有大數據組件的趨勢之一。Spark在其設計之初將與資源管理框架的交互抽象化,並支持多種資源管理框架,如YARN,Mesos等。而從2.3版本開始官方適配了k8s,能夠以容器化的方式啟動Spark應用程序並調度executor。Spark on Kubernetes的主要架構如下所示:
在後續的版本中,Spark on Kubernetes也逐步補齊了與其他資源管理框架支持上的差異,並預期在Spark 3.0中將其GA。相信隨著Spark on Kubernetes的成熟,大數據容器化技術的進化,使用容器化會是不二之選。
存儲計算分離
在前面的背景中也提到了由於網絡帶寬的增加和異構集群的流行,存儲計算分離再度流行,尤其是在雲上環境,塊存儲 (Blob Storage)、雲盤已經成為主流,主流的虛擬機配置中只有少量的本地硬盤作為系統盤和本地緩存,同時配置雲盤作為數據盤。在這樣的情況下,數據中心的架構變為了如下的形態:
存儲計算分離對於現在的MR是框架的挑戰主要有:
1.數據本地性的約束已不復存在,所有的輸入數據都是通過遠程讀取的,因此針對數據本地性的任務調度策略已沒有多大意義。
2.所有的本地存儲 (比如shuffle,spill) 都會涉及到網絡傳輸,因此基於本地硬盤的shuffle方式已不是最佳選擇,會帶來額外的代價。
既然所有的數據都是通過遠程進行讀寫,那何不利用這樣的特性來設計一個更為合理的shuffle框架呢?為此Spark在3.0以後正式引入remote shuffle的方式,以適應存儲計算分離的架構。SPARK-25299[2]將Spark的shuffle讀寫與shuffle邏輯解耦並框架化,剝離出與本地系統交互的部分,後續可以基於SPARK-25299的框架來實現remote shuffle,例如Splash[3]。
對象存儲的支持
在雲上環境中,數據持久化已不再交由虛擬機的本地硬盤,更多的則是使用塊存儲或是對象存儲,而對於海量數據的存取,對象存儲是一個廉價而高效的解決方案。對象存儲,其高擴展性以及海量文件存儲的能力,非常適合大數據存儲,但是另一方由於其原子性語義的缺失、較弱的一致性、list, rename較高的代價,也會為大數據處理帶來一定的問題。
那如何來解決對象存儲帶來的問題,更好地支持對象存儲呢?
1.在Hadoop層面上實現更好的FileSystem API,如S3A[4],來解決上面提到的問題。
2.在數據組織形態上設計更好的結構,來規避上述提到的問題,比如Spark所支持的Apache Iceberg[5],Delta Lake[6],Apache Hudi[7]。
彈性化調度
雲上環境的計算資源是易失的,像是AWS,Azure都會提供更為廉價的易失性實例,為了能更好地使用這些易失性實例,需要分佈式計算框架將fault tolerance作為常態考慮。這樣就需要儘可能地將狀態的保存從本地存儲遷移到遠端可靠集群上去。SPARK-25299[8] remote shuffle的可以有效地避免本地狀態 (shuffle) 的保存,是的計算節點變為無狀態的,更好地支持易失性的場景。
同時在雲上環境中,為了更好地利用計算資源,控制計算成本,分佈式框架也需要及時主動地釋放資源,做到彈性擴縮容。Spark從1.2版本起就支持executor級別的彈性擴縮容來更好的利用executor資源。但是在雲上環境,光是釋放executor資源是不夠的,更進一步的是需要釋放計算實例,為此需要將Spark的彈性擴縮容策略進一步改進,以更好地支持雲上實例的動態擴縮容。
總結
本文從大數據的基本架構以及軟硬件演進的歷史介紹了大數據框架在雲原生時代下的挑戰。同時也從4方面詳細介紹了Spark在應對雲原生時代的進化。大數據框架在不斷地迭代演進中以適應新的基礎架構,在ABC時代擁抱雲、融入雲,打造更好的雲原生大數據框架必定會是未來的發展方向。
References
[1] Spark: https://spark.apache.org/
[2] SPARK-25299: https://issues.apache.org/jira/browse/SPARK-25299
[3] Splash: https://github.com/MemVerge/splash
[4] S3A: https://hadoop.apache.org/docs/current/hadoop-aws/tools/hadoop-aws/index.html
[5] Apache Iceberg: https://iceberg.incubator.apache.org/
[6] Delta Lake: https://delta.io/
[7] Apache Hudi: https://hudi.incubator.apache.org/
[8] SPARK-25299: https://issues.apache.org/jira/browse/SPARK-25299
阿里巴巴開源大數據技術團隊成立Apache Spark中國技術社區,定期推送精彩案例,技術專家直播,問答區近萬人Spark技術同學在線提問答疑,只為營造純粹的Spark氛圍,歡迎釘釘掃碼加入!
對開源大數據和感興趣的同學可以加小編微信(下圖二維碼,備註“進群”)進入技術交流微信群。Apache
Spark技術交流社區公眾號,微信掃一掃關注