1. 程式人生 > >基礎概念 之 Spark on Yarn

基礎概念 之 Spark on Yarn

資源 兩個 htm 底層 兩種 nta 一起 () 所在

先拋出問題:Spark on Yarn有cluster和client兩種模式,它們有什麽區別? 用Jupyter寫Spark時,只能使用client模式,為什麽?

寫一篇文章,搞清楚 Spark on Yarn 的運行原理,同時回答上面的問題。

首先,把Spark和Yarn當做兩個獨立概念來看。單看Spark,不去管它底層依賴的存儲結構,本質上講,它就是個分布式計算的程序。程序的入口是一個叫做 SparkContext 的對象,也可以抽象地稱為Driver,啟動了 SparkContext 後,就可以運行各種Spark方法(比如 map,filter)。運行方法時,Spark會把每次執行分解成若幹個Task,分發給若幹個Executor執行,Executor是執行Task的進程,執行後的結果匯總到一起,返回給 SparkContext。Spark 本質上也是一個map+reduce的過程,與Hadoop不同的是,Spark會先把數據存儲到內存中,這樣處理速度會比Hadoop快大約兩個數量級。

這麽多的Executor進程是怎麽來的?

是Yarn分配的。(註:還有其他資源管理框架,比如 Moses,這裏先不管它。)

再次強調,Spark只是一套可以運行的代碼,代碼運行是需要資源的(計算、存儲、網絡),Yarn是給Spark提供運行資源的。

Yarn本身的運行方式是:Yarn把集群的節點分為兩類,一類是Master,運行的進程叫ResourceManager(簡稱RM),另一類是Worker,運行的進程叫NodeManager(簡稱NM),NM可以在本機內分配資源,生成若幹個Container(不熟悉容器的同學可以把Container近似理解為虛擬機)。Yarn的運行過程是,RM接受外部的資源申請(可以來自Hadoop、Spark或其他進程),按照要求分配資源,然後把對應的資源分配計劃通知各個NM,NM收到自己的分配計劃,按計劃在本地啟動若幹個Container。

Spark和Yarn各自介紹完畢。

Spark on Yarn就是把上述過程結合起來,Yarn在底層,Spark在上層,也就是說,我們在寫Spark代碼時不需要操作Yarn,只需要設置好Spark的資源參數,Yarn會按照Spark的資源參數去分配資源,然後提供給Spark使用。

Spark on Yarn 的運行過程是:SparkContext運行起來,設置資源參數,Yarn中會為每個Spark App啟動一個Container,叫做App Master,由App Master把資源參數發送給RM,RM通知若幹個NM,啟動若幹個Container,每個Container內部都運行一個Executor,對,就是Spark中的Executor,這樣Spark 和 Yarn 就結合起來了。

這裏給出一個Spark on Yarn的資源參數配置示例:

conf = SparkConf().setMaster(yarn-client).setAppName(test)
conf.set(spark.executor.instances,10)
conf.set(spark.executor.cores,1)
conf.set(spark.executor.memory,2g)
conf.set("spark.driver.memory", "2g")
conf.set("spark.driver.maxResultSize", "0")

Spark on Yarn的原理都清楚了,下面要解決開頭提出的問題了:Spark on Yarn 的 cluster 和 client 模式有什麽區別?為什麽Jupyter只能用client模式?

對比cluster和client,從名字就可以看出,前者是分布式的,後者是本地化的。具體區別就在於上面的紅字:App Master的作用不同。

在cluster模式中,SparkContext運行在App Master所在的Container中,也就是說,在初始化Spark程序時,我們不知道SparkContext會運行在哪個節點,由RM分配一個Container作為App Master後,SparkContext運行在這個Container中,Spark程序的運行與我們在哪個節點啟動它沒有關系。

相對地,在client模式中,SparkContext運行在啟動SparkContext的節點上,所有與Spark有關的調度工作都在這個節點上運行(註意:不是在這個節點的Container上),App Master只在向RM申請資源時起到了作用,之後就它什麽事了,除非資源需要發生變化。

到這裏,我們就能明白為什麽Jupyter必須使用client模式了,因為Jupyter是運行在節點上的進程,只能和本地節點的內存實現數據交互。(跨節點內存交互也不是完全不可能,但是基本沒用。)

參考資料:

https://www.cnblogs.com/tgzhu/p/5818374.html

基礎概念 之 Spark on Yarn