Spark On Yarn的兩種模式yarn-cluster和yarn-client深度剖(pou)析
Spark On Yarn的優勢
我們知道Spark on yarn有兩種模式:yarn-cluster和yarn-client。這兩種模式作(zuo)業雖然都是在yarn上面運(yun)行(xing),但是其中的(de)運(yun)行(xing)方式很不一樣,今天就(jiu)來談談Spark on YARN yarn-client模式作(zuo)業從提交(jiao)到運(yun)行(xing)的(de)過程(cheng)剖(pou)析
相關概(gai)念
- Application: Appliction都是指用戶編寫的Spark應用程序,其中包括一個Driver功能的代碼和分布在集群中多個節點上運行的Executor代碼
- Driver: Spark中的Driver即運行上述Application的main函數并創建SparkContext,創建SparkContext的目的是為了準備Spark應用程序的運行環境,在Spark中有SparkContext負責與ClusterManager通信,進行資源申請、任務的分配和監控等,當Executor部分運行完畢后,Driver同時負責將SparkContext關閉,通常用SparkContext代表Driver
- Executor: 某個Application運行在worker節點上的一個進程, 該進程負責運行某些Task, 并且負責將數據存到內存或磁盤上,每個Application都有各自獨立的一批Executor, 在Spark on Yarn模式下,其進程名稱為CoarseGrainedExecutor Backend。一個CoarseGrainedExecutor Backend有且僅有一個Executor對象, 負責將Task包裝成taskRunner,并從線程池中抽取一個空閑線程運行Task, 這個每一個oarseGrainedExecutor Backend能并行運行Task的數量取決與分配給它的cpu個數
- Cluter Manager:指的是在集群上獲取資源的外部服務。目前有三種類型
- Standalon : spark原生的資源管理,由Master負責資源的分配
- Apache Mesos:與hadoop MR兼容性良好的一種資源調度框架
- Hadoop Yarn: 主要是指Yarn中的ResourceManager
- Worker: 集群中任何可以運行Application代碼的節點,在Standalone模式中指的是通過slave文件配置的Worker節點,在Spark on Yarn模式下就是NoteManager節點
- Task: 被送到某個Executor上的工作單元,但hadoopMR中的MapTask和ReduceTask概念一樣,是運行Application的基本單位,多個Task組成一個Stage,而Task的調度和管理等是由TaskScheduler負責
- Job: 包含多個Task組成的并行計算,往往由Spark Action觸發生成, 一個Application中往往會產生多個Job
- Stage: 每個Job會被拆分成多組Task, 作為一個TaskSet, 其名稱為Stage,Stage的劃分和調度是有DAGScheduler來負責的,Stage有非最終的Stage(Shuffle Map Stage)和最終的Stage(Result Stage)兩種,Stage的邊界就是發生shuffle的地方
- DAGScheduler: 根據Job構建基于Stage的DAG(Directed Acyclic Graph有向無環圖),并提交Stage給TASkScheduler。 其劃分Stage的依據是RDD之間的依賴的關系找出開銷最小的調度方法,如下圖

- TASKSedulter: 將TaskSET提交給worker運行,每個Executor運行什么Task就是在此處分配的. TaskScheduler維護所有TaskSet,當Executor向Driver發生心跳時,TaskScheduler會根據資源剩余情況分配相應的Task。另外TaskScheduler還維護著所有Task的運行標簽,重試失敗的Task。下圖展示了TaskScheduler的作用

- 在不同運行模式中任務調度器具體為:
- Spark on Standalone模式為TaskScheduler
- YARN-Client模式為YarnClientClusterScheduler
- YARN-Cluster模式為YarnClusterScheduler
- 將這些術語串起來的運行層次圖如下:

- Job=多個stage,Stage=多個同種task, Task分為ShuffleMapTask和ResultTask,Dependency分為ShuffleDependency和NarrowDependency
Spark運行模式:
- Spark的運行模式多種多樣,靈活多變,部署在單機上時,既可以用本地模式運行,也可以用偽分布模式運行,而當以分布式集群的方式部署時,也有眾多的運行模式可供選擇,這取決于集群的實際情況,底層的資源調度即可以依賴外部資源調度框架,也可以使用Spark內建的Standalone模式。
- 對于外部資源調度框架的支持,目前的實現包括相對穩定的Mesos模式,以及hadoop YARN模式
- 本地模式:常用于本地開發測試,本地還分別 local 和 local cluster
YARN-Client
在Yarn-client中,Driver運行在Client上,通過ApplicationMaster向RM獲取資源。本地Driver負責(ze)與所有的executor container進行交(jiao)互,并將最后的結果匯總。結束掉終(zhong)端,相當于(yu)kill掉這個spark應用(yong)。
因(yin)為(wei)Driver在客戶端(duan),所以可以通過webUI訪(fang)問Driver的(de)狀態,默(mo)認是//hadoop1:4040訪(fang)問,而YARN通過// hadoop1:8088訪(fang)問
- YARN-client的工(gong)作流程步驟為:


- Spark Yarn Client向YARN的ResourceManager申請啟動(dong)Application Master。同時(shi)在SparkContent初始化中將(jiang)創建DAGScheduler和TASKScheduler等,由于我們選擇(ze)(ze)的是(shi)Yarn-Client模式(shi),程序會選擇(ze)(ze)YarnClientClusterScheduler和YarnClientSchedulerBackend
- ResourceManager收到(dao)請求(qiu)后(hou),在集群中選擇(ze)一(yi)個NodeManager,為該應用(yong)程序(xu)分配第一(yi)個Container,要求(qiu)它在這個Container中啟(qi)動應用(yong)程序(xu)的ApplicationMaster,與(yu)(yu)YARN-Cluster區(qu)別的是在該ApplicationMaster不運行SparkContext,只與(yu)(yu)SparkContext進(jin)(jin)行聯系進(jin)(jin)行資源的分派(pai)
- Client中的SparkContext初(chu)始化完畢后,與ApplicationMaster建立通訊,向(xiang)ResourceManager注冊,根據(ju)任務(wu)信息向(xiang)ResourceManager申(shen)請資(zi)源(Container)
- 一旦ApplicationMaster申(shen)請(qing)到資源(也(ye)就是Container)后(hou),便(bian)與對應(ying)的NodeManager通信,要求它在獲得的Container中(zhong)啟動(dong)CoarseGrainedExecutorBackend,CoarseGrainedExecutorBackend啟動(dong)后(hou)會(hui)向Client中(zhong)的SparkContext注冊并申(shen)請(qing)Task
- client中(zhong)的SparkContext分配Task給(gei)CoarseGrainedExecutorBackend執行,CoarseGrainedExecutorBackend運行Task并向Driver匯報運行的狀態和進度,以(yi)讓Client隨(sui)時(shi)掌握各(ge)個任務的運行狀態,從而可以(yi)在(zai)任務失敗(bai)時(shi)重新啟動任務
- 應用程序(xu)運行完成后,Client的SparkContext向ResourceManager申請注(zhu)銷并關(guan)閉自己
因為是(shi)與Client端通信,所以Client不能關閉。
客戶端的(de)(de)Driver將應用提交給Yarn后,Yarn會(hui)先后啟動ApplicationMaster和executor,另外ApplicationMaster和executor都 是(shi)(shi)裝(zhuang)載在(zai)(zai)container里運行,container默認的(de)(de)內(nei)(nei)存(cun)是(shi)(shi)1G,ApplicationMaster分(fen)配的(de)(de)內(nei)(nei)存(cun)是(shi)(shi)driver- memory,executor分(fen)配的(de)(de)內(nei)(nei)存(cun)是(shi)(shi)executor-memory。同時,因為(wei)Driver在(zai)(zai)客戶端,所以程序的(de)(de)運行結(jie)果可(ke)以在(zai)(zai)客戶端顯 示,Driver以進(jin)程名(ming)為(wei)SparkSubmit的(de)(de)形式存(cun)在(zai)(zai)。
Yarn-Cluster
- 在YARN-Cluster模式中,當用戶向YARN中提交一個應用程序后,YARN將分兩個階段運行該應用程序:
- 第一個階段是把Spark的Driver作為一個ApplicationMaster在YARN集群中先啟動;
- 第二個階段是由ApplicationMaster創建應用程序,然后為它向ResourceManager申請資源,并啟動Executor來運行Task,同時監控它的整個運行過程,直到運行完成
應用的(de)運行結果不能在(zai)客戶(hu)端顯(xian)示(可(ke)以在(zai)history server中查看),所以最好將結果保存在(zai)HDFS而(er)非(fei)stdout輸出,客戶(hu)端的(de)終端顯(xian)示的(de)是(shi)(shi)作為YARN的(de)job的(de)簡(jian)單運行狀況,下圖是(shi)(shi)yarn-cluster模(mo)式


執(zhi)行過程:
- Spark Yarn Client向YARN中(zhong)(zhong)提(ti)交應(ying)用(yong)程(cheng)(cheng)序,包括ApplicationMaster程(cheng)(cheng)序、啟(qi)動(dong)ApplicationMaster的(de)命令、需要在Executor中(zhong)(zhong)運行的(de)程(cheng)(cheng)序等
- ResourceManager收到請求后,在集群中選(xuan)擇一個(ge)NodeManager,為(wei)該應用(yong)程序分配第一個(ge)Container,要求它在這個Container中啟動應用程序的ApplicationMaster,其中ApplicationMaster進行SparkContext等的初始化
- ApplicationMaster向ResourceManager注冊,這樣用戶可以直接通過ResourceManage查看應用程序的運行狀態,然后它將采用輪詢的方式通過RPC協議為各個任務申請資源,并監控它們的運行狀態直到運行結束
- 一旦ApplicationMaster申請到資源(yuan)(也就(jiu)是Container)后,便與對應的NodeManager通信,要求它在獲得的Container中啟動CoarseGrainedExecutorBackend,而Executor對象的創(chuang)建(jian)及維護(hu)是由CoarseGrainedExecutorBackend負責的,CoarseGrainedExecutorBackend啟動后會向ApplicationMaster中的SparkContext注冊并(bing)申請Task。這一點和Standalone模式一樣,只不過SparkContext在Spark Application中初始化時,使用CoarseGrainedSchedulerBackend配合YarnClusterScheduler進行任務的調度,其中YarnClusterScheduler只是對TaskSchedulerImpl的一個簡單包裝,增加了對Executor的等待邏輯等
- ApplicationMaster中的SparkContext分配Task給CoarseGrainedExecutorBackend執行,CoarseGrainedExecutorBackend運行Task并向ApplicationMaster匯報運行的狀態和進度,以讓ApplicationMaster隨時掌握各個任務的運行狀態,從而可以在任務失敗時重新啟動任務
- 應用程序運行完成后,ApplicationMaster向ResourceManager申請注(zhu)銷并(bing)關閉自(zi)己
比以前的更多的理解(jie):
(1)Application Master所(suo)在的(de)NodeManager是(shi)Yarn隨機分配的(de),不是(shi)在主(zhu)節(jie)點(dian)上(shang),下圖是(shi)實驗(yan)室集群上(shang)跑(pao)得一個(ge)Spark程序,tseg0是(shi)主(zhu)節(jie)點(dian),tseg1~tseg4是(shi)workers,IP10.103.240.29指的(de)是(shi)tseg3:

(2)在上圖還(huan)可以看(kan)出(chu),executor的(de)容器和AM容器是可以共(gong)存的(de),它們的(de)封裝(zhuang)都是容器;
(3)AM是Yarn啟動的第(di)一個容器;
(4)AM所在的(de)(de)NodeManager就是平常說(shuo)的(de)(de)Driver端,因為(wei)這(zhe)(zhe)個AM啟動(dong)了SparkContext,之前實(shi)驗室說(shuo)的(de)(de)“誰初(chu)始化的(de)(de)SparkContext誰就是Driver端”一直理(li)解錯了,以為(wei)這(zhe)(zhe)句話是相對于機(ji)器說(shuo)的(de)(de),但(dan)其實(shi)是相對于Cluster和Client的(de)(de)集群模式來說(shuo)的(de)(de)(不(bu)知道其他(ta)模式Mesos、standalone是不(bu)是也是這(zhe)(zhe)樣)。
(5)在(zai)Application提(ti)交(jiao)到RM上(shang)之后(hou),Client就(jiu)可以關閉了,集群會繼續運(yun)(yun)行(xing)提(ti)交(jiao)的程(cheng)序,在(zai)實際使用時,有時候會看到這樣一種(zhong)現象,關閉Client會導致程(cheng)序終止,其實這個Application還沒有提(ti)交(jiao)上(shang)去,關閉Client打斷了提(ti)交(jiao)的過程(cheng),Application當然不(bu)會運(yun)(yun)行(xing)。
YARN-Cluster和YARN-Client的(de)區別
- 理解YARN-Client和(he)YARN-Cluster深層次的區別之(zhi)前先清楚一個概(gai)念:Application Master。在YARN中,每個Application實例都(dou)有一個ApplicationMaster進(jin)(jin)程(cheng),它是Application啟動的第一個容器。它負責和(he)ResourceManager打交道并請求資(zi)源,獲取資(zi)源之(zhi)后告(gao)訴NodeManager為(wei)其啟動Container。從深層次的含義講YARN-Cluster和(he)YARN-Client模式(shi)的區別其實就(jiu)是ApplicationMaster進(jin)(jin)程(cheng)的區別
- YARN-Cluster模(mo)式下,Driver運行(xing)(xing)在(zai)AM(Application Master)中,它負責向YARN申請(qing)資源,并(bing)監(jian)督(du)作業(ye)的運行(xing)(xing)狀況。當(dang)用戶提交了作業(ye)之后(hou),就可以關掉(diao)Client,作業(ye)會繼續在(zai)YARN上運行(xing)(xing),因而YARN-Cluster模(mo)式不適合運行(xing)(xing)交互類型的作業(ye)
- YARN-Client模式下,Application Master僅僅向YARN請(qing)求Executor,Client會和請(qing)求的Container通(tong)信來(lai)調(diao)度(du)他們工作,也(ye)就是說Client不能離開
(1)YarnCluster的(de)Driver是在(zai)集(ji)群的(de)某(mou)一臺NM上(shang),但是Yarn-Client就是在(zai)RM的(de)機器(qi)上(shang);
(2)而Driver會和Executors進行(xing)通信,所以Yarn_cluster在提交(jiao)App之后可以關(guan)閉(bi)Client,而Yarn-Client不可以;
(3)Yarn-Cluster適合(he)(he)生產環境(jing),Yarn-Client適合(he)(he)交互(hu)和調(diao)試。
下(xia)表是Spark Standalone與Spark On Yarn模式(shi)下(xia)的(de)比較

Reference
- 《Spark技(ji)術(shu)內(nei)幕(mu)-深入(ru)解析Spark內(nei)核、架構(gou)設計與實現原(yuan)理》
- Spark Yarn-cluster與Yarn-client



