1、首先我們來看一下yarn運作時的架構圖
yarn的運作流程
- 使用者向 YARN 中送出應用程式,其中包括 MRAppMaster 程式,啟動 MRAppMaster 的指令,使用者程式等。
- ResourceManager 為該程式配置設定第一個 Container,并與對應的 NodeManager 通訊,要求它在這個 Container 中啟動應用程式 MRAppMaster。
- MRAppMaster 首先向 ResourceManager 注冊,這樣使用者可以直接通過 ResourceManager檢視應用程式的運作狀态,然後将為各個任務申請資源,并監控它的運作狀态,直到運作結束,重複 4 到 7 的步驟。
- MRAppMaster 采用輪詢的方式通過 RPC 協定向 ResourceManager 申請和領取資源。
- 一旦 MRAppMaster 申請到資源後,便與對應的 NodeManager 通訊,要求它啟動任務。
- NodeManager 為任務設定好運作環境(包括環境變量、JAR 包、二進制程式等)後,将任務啟動指令寫到一個腳本中,并通過運作該腳本啟動任務。
- 各個任務通過某個 RPC 協定向 MRAppMaster 彙報自己的狀态和進度,以讓 MRAppMaster随時掌握各個任務的運作狀态,進而可以在任務敗的時候重新啟動任務。
- 應用程式運作完成後,MRAppMaster 向 ResourceManager 登出并關閉自己。
2、AppMaster和Driver
上面了解了appmaster在yarn運作流程中的角色,再區分下AppMaster和Driver,任何一個yarn上運作的任務都必須有一個AppMaster,而任何一個Spark任務都會有一個Driver,Driver就是運作SparkContext(它會建構TaskScheduler和DAGScheduler)的程序,當然在Driver上你也可以做很多非Spark的事情,這些事情隻會在Driver上面執行,而由SparkContext上牽引出來的代碼則會由DAGScheduler分析,并形成Job和Stage交由TaskScheduler,再由TaskScheduler交由各Executor分布式執行。
是以Driver和AppMaster是兩個完全不同的東西,Driver是控制Spark計算和任務資源的,而AppMaster是控制yarn app運作和任務資源的,隻不過在Spark on Yarn上,這兩者就出現了交叉,而在standalone模式下,資源則由Driver管理。在Spark on Yarn上,Driver會和AppMaster通信,資源的申請由AppMaster來完成,而任務的排程和執行則由Driver完成,Driver會通過與AppMaster通信來讓Executor的執行具體的任務。
3、client與cluster的差別
對于yarn-client和yarn-cluster的唯一差別在于,yarn-client的Driver運作在本地,而AppMaster運作在yarn的一個節點上,他們之間進行遠端通信,AppMaster隻負責資源申請和釋放(當然還有DelegationToken的重新整理),然後等待Driver的完成;而yarn-cluster的Driver則運作在AppMaster所在的container裡,Driver和AppMaster是同一個程序的兩個不同線程,它們之間也會進行通信,AppMaster同樣等待Driver的完成,進而釋放資源。
Spark裡AppMaster的實作:org.apache.spark.deploy.yarn.ApplicationMaster
Yarn裡MapReduce的AppMaster實作:org.apache.hadoop.mapreduce.v2.app.MRAppMaster
1、在yarn-client模式裡
優先運作的是Driver(我們寫的應用代碼就是入口),然後在初始化SparkContext的時候,會作為client端向yarn申請AppMaster資源,當AppMaster運作後,它會向yarn注冊自己并申請Executor資源,之後由本地Driver與其通信控制任務運作,而AppMaster則時刻監控Driver的運作情況,如果Driver完成或意外退出,AppMaster會釋放資源并登出自己。是以在該模式下,如果運作spark-submit的程式退出了,整個任務也就退出了。
2、在yarn-cluster模式裡
本地程序則僅僅隻是一個client,它會優先向yarn申請AppMaster資源運作AppMaster,在運作AppMaster的時候通過反射啟動Driver(我們的應用代碼),在SparkContext初始化成功後,再向yarn注冊自己并申請Executor資源,此時Driver與AppMaster運作在同一個container裡,是兩個不同的線程,當Driver運作完畢,AppMaster會釋放資源并登出自己。是以在該模式下,本地程序僅僅是一個client,如果結束了該程序,整個Spark任務也不會退出,因為Driver是在遠端運作的
3、送出任務:
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \ # can be client for cluster mode
--executor-memory 20G \
--num-executors 50 \
/path/to/examples.jar
YARN cluster
./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
--driver-memory 4g \
--executor-memory 2g \
--executor-cores 1 \
--queue thequeue \
lib/spark-examples*.jar \
最後總結一句:client在本地環境測試的時候經常使用,而cluster則是在生成環境中使用。