大數據Spark YarnCluster模式源碼分析——提交任務(圖文並茂)

寫在前面的話:本篇博客爲原創,認真閱讀需要比對spark 2.1.1的源碼,預計閱讀耗時30分鐘,如果大家發現有問題或者是不懂的,歡迎討論
歡迎關注公衆號:後來X

spark 2.1.1的源碼包(有需要自取):關注公衆號【後來X】,回覆spark源碼

第一次寫博客,寫的有啥問題,歡迎大家留言評論,一定每週更新,哈哈!

今天主要分析的是spark的YarnCluster模式下的提交任務的源碼,那麼我們先看一下流程圖
在這裏插入圖片描述
開始啃源碼吧,爲了啃源碼更高效,希望大家把這張流程圖搭配着一起看,可以時刻知道現在到哪一步了。

正式開始源碼分析

Spark-submit命令

說到提交任務,不管是什麼spark的哪種運行模式,提交任務的命令都少不了Spark-submit,下面以提交wordCount的項目的命令爲例:

bin/spark-submit \
--class com.later.WordCount \
--master yarn \
--deploy-mode cluster \
./test/jars/spark-WordCount.jar \
10

那我們提交完之後,都會有一個spark-submit的線程,所以在spark源碼中,double shift我們先找到SparkSubmit.scala

  1. 先找到main方法,並且提交參數的 .action 默認爲submit,所以匹配到提交作業的命令:submit(appArgs)
    找到main方法

  2. 準備提交job的環境:prepareSubmitEnvironment(args)
    準備提交環境
    在這個裏面,主要是對參數的賦值,我們額外注意childMainClass,通過ctrl+F搜索,發現:
    cluster模式->childMainClass = “org.apache.spark.deploy.yarn.Client”
    client模式->childMainClass = “com.later.WordCount”

  3. 最後doRunMain(),點進去
    在這裏插入圖片描述

  4. 判斷代理是否爲null,無論是if還是else,都執行
    runMain(childArgs, childClasspath, sysProps, childMainClass, args.verbose)
    在這裏插入圖片描述

  5. 在這裏發現:定義了一個mainClass對象,並把上面第2步拿到的childMainClass賦給了mainClass
    在這裏插入圖片描述

  6. 並且往下滑,發現還通過反射的方式獲得mainClass中的main方法,賦給了mainMethod
    在這裏插入圖片描述

  7. 將mainClass中的main方法當做自己的方法調用(回調)
    在這裏插入圖片描述
    此時的mainClass對象爲:org.apache.spark.deploy.yarn.Client

yarnClient的啓動

因爲在上一次submit最終回調的是這個Client裏面的main方法,所以double shift找到org.apache.spark.deploy.yarn.Client

  1. 找到main方法,並且創建了Client,執行了run方法
    在這裏插入圖片描述

  2. 向ResourceManager提交申請,獲取appID,點進去
    在這裏插入圖片描述

  3. 既然提出申請,那就需要
    **創建申請: ** val newApp = yarnClient.createApplication()
    創建該申請的響應: val newAppResponse = newApp.getNewApplicationResponse()
    設置啓動AM的環境:
    val appContext = createApplicationSubmissionContext(newApp, containerContext)
    在這裏插入圖片描述

  4. 這是設置適當的上下文來啓動AM,也就是封裝命令的具體內容 :
    val containerContext = createContainerLaunchContext(newAppResponse)
    那麼既然要啓動AM,就需要有相應的參數,在該方法中點進去,可以看到:javaOpts+=內存,GC,日誌
    並且獲取到了val userClass = 我們在提交任務的時候,–class 之後提交的參數,例如“com.later.wordCount”,並且還拿到了amClass
    cluster->val amClass = “org.apache.spark.deploy.yarn.ApplicationMaster”
    client->amClass=“org.apache.spark.deploy.yarn.ExecutorLauncher”
    在這裏插入圖片描述
    AM的命令:val commands =
    /bin/java “org.apache.spark.deploy.yarn.ApplicationMaster” --class WordCount…

  5. 接着第3步往下,看到了提交命令:yarnClient.submitApplication(appContext)
    在這裏插入圖片描述
    到此,Client已經向RM提交了申請,由RM指定一個NM來執行封裝的命令,啓動AM

ApplicationMaster的啓動

所以我們接下來的代碼應該從上面的command中:org.apache.spark.deploy.yarn.ApplicationMaster

  1. 先找到main方法,那既然是來啓動AM的,所以就先創建一個AM,並且執行了master.run()
    在這裏插入圖片描述

  2. 接下來看run方法,大多數都是變量的賦值,其中包括創建HDFS文件系統:val fs = FileSystem.get(yarnConf)
    在這裏插入圖片描述

  3. 並且找到Driver的執行:runDriver(securityMgr)
    在這裏插入圖片描述

  4. 在Driver方法中,啓動了用戶類線程:userClassThread = startUserApplication()
    在這裏插入圖片描述

  5. 用戶類線程中:用類加載器的方式來加載用戶類的main方法,並且,爲這個線程設置名稱爲"Driver",驗證了在yarn的cluster模式下,Driver運行在集羣(在client模式下,Driver運行在客戶端)
    在這裏插入圖片描述

  6. 如圖第4步中,除了用戶類線程,還有向RM註冊AM

  7. 現在有了AM,得需要向RM申請資源:allocator.allocateResources(),這裏的方法名是分配資源:爲RM爲AM分配資源,也就是我說的申請資源
    在這裏插入圖片描述

  8. 既然申請資源,肯定得獲取資源容器, 判斷申請到的資源容器大小是不是大於0,也就是說如果RM沒資源了,返回的肯定是個空的容器,如果>0,就進行處理這些資源:
    在這裏插入圖片描述

  9. 對獲取到的資源進行分類(同一機架還是什麼情況)
    在這裏插入圖片描述

  10. 啓動runAllocatedContainers(containersToUse),就是在這個Container裏面運行ExecutorBackend
    在這裏插入圖片描述

  11. 遍歷可用的資源容器,對每一個進行如下操作:
    for (container <- containersToUse) {
    launcherPool.execute{new ExecutorRunnable().run()},找到了run方法
    在這裏插入圖片描述

  12. 真正啓動Container
    在這裏插入圖片描述

  13. 那startContainer()這個啓動方法進去,看一下是怎麼啓動的
    ctx對命令進行了設置,ctx.setCommands(commands.asJava)
    並且讓NMClient開始運行 容器:nmClient.startContainer(container.get, ctx)
    在這裏插入圖片描述
    其中的準備命令爲:val commands = prepareCommand(),點進去發現和之前的Client中的第4步有點類似。
    在這裏插入圖片描述
    命令是這樣的:
    /bin/java org.apache.spark.executor.CoarseGrainedExecutorBackend

以上是Yarn Cluster模式下,從Spark-submit提交任務開始,到Excutor執行的全過程
那我們再次返回來看這張流程圖,是不是覺得前面的部分已經比較熟悉了。
下一篇我們能繼續看ExecutorBackend以及任務的劃分,下一篇再見。

最後再來一波,喜歡我的歡迎點贊,歡迎關注我的公衆號:後來X,回覆:spark源碼,獲取spark2.1.1源碼包

持續更新,未完待續!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章