Spark源碼系列-Yarn模式下Client&Cluster模式的資源啟動

本文帶讀者從源碼查看,分析Yarn模式下Client&Cluster模式的資源啟動流程,分析Client&Cluster究竟有什么不一樣

回顧

在xxxx中我們分析了Standalone模式下Master和Worker的啟動流程。


image.png
  • Master負責集群總資源的管理,包括CPU、內存的分配以及所有Applications的管理、Cluster模式下還有所有的driver的管理。Master啟動后會定時清理沒有上報心跳的Worker
  • Master啟動后會向Master注冊自己(RegisterWorker),將自己的CPU cores和內存大小上報給Master,并定時發(fā)送心跳,更新Master里面屬于自己ID的時間戳

資源有了,接下來需要啟動我們自己的Application。

SparkSubmit提交代碼

image.png
image.png

通過分析spark-submit腳本,我們知道最終啟動的是SparkSubmit類,接下來的調用流程如下所示。


image.png

最終通過prepareSumitEnvironment解析出mainClass,最終在SparkApplication start方法中,通過反射調用MainClass的main方法,解析的MainClass如下

image.png

Yarn Client 源碼分析

由上可知,最終我們解析的是用戶的Class,而最重要的類就是SparkContext,高版本是SparkSession,本質是將SparkContext作為SparkSession的成員變量。

Yarn Client 總架構

SparkSession

SparkSession將SparkContext作為的自己成員變量

image.png
image.png

SparkContext

createTaskScheduler

重點需要看createTaskScheduler方法,然后調用start

image.png

TaskSchedulerImpl

這里會創(chuàng)建TaskSchedulerImpl和StandaloneSchedulerBackend,并通過initialize將StandaloneSchedulerBackend放入TaskSchedulerImpl中,結合上圖,會調用StandaloneSchedulerBackend的start方法


image.png
image.png
image.png

這里的cm(clusterManager)是 YarnClusterManager,scheduler是YarnScheduler, backend是YarnClientSchedulerBackend

YarnClusterManager.initialize() 方法

YarnClusterManager繼承TaskSchedulerImpl,
將Backend作為自己的成員變量,并通過schedulingMode創(chuàng)建調度是FIFOSchedulableBuilder還是FairSchedulableBuilder,這里是提交task的時候用到的調度方式


image.png

YarnClientSchedulerBackend

YarnClientSchedulerBackend繼承YarnSchedulerBackend,YarnSchedulerBackend 繼承CoarseGrainedSchedulerBackend


image.png

start方法第一部分

首先調用super.start,查看super.start方法為CoarseGrainedSchedulerBackend的start方法

image.png

CoarseGrainedSchedulerBackend.start()

image.png

這里調用了createDriverEndpointRef,可以看到關鍵詞driver了,其實driver本質上的類是DriverEndpoint,結合Spark RPC框架,我們可以知道Driver的生命周期方法。

onStart() 和 receive

這里啟動一個定時線程,定時給自己發(fā)送ReviveOffers,給自己發(fā)送case class ReviveOffers

image.png
makeOffers

通過命名方式我們可以知道,這里是在獲取可用的executors的資源,將task信息包裝成taskDescs,在Executor上啟動task


image.png

將task序列化后發(fā)送給Executor,但是這里并未真正執(zhí)行,因為還沒有申請到Executor資源,所以onstart里的定時線程將會一直嘗試執(zhí)行,直到申請到executor,就會在上面launchTasks


image.png

Driver

本質上Driver是CoarseGrainedSchedulerBackend里的一個成員變量,負責序列化并通過RPC發(fā)送給有資源的Executor執(zhí)行task,但是在這里并沒有執(zhí)行,因為還沒有申請到執(zhí)行資源Executor。接下來回到我們的YarnSchedulerBackend中

image.png

start方法第二部分

第一部分調用了super.start我們知道了Driver的本質和職責接下來,看第二部分

image.png
org.apache.spark.deploy.yarn.Client

Client中有一個yarnClient成員變量,與yarn集群做RPC通信,提交Application使用

image.png
org.apache.spark.deploy.yarn.Client. submitApplication
image.png

createContainerLaunchContext中會申請ApplicationMaster的啟動信息,并指定啟動類,

  • cluster模式: org.apache.spark.deploy.yarn.ApplicationMaster
  • client模式:org.apache.spark.deploy.yarn.ExecutorLauncher


    image.png
ExecutorLauncher

什么也沒有做,就是調用了ApplicationMaster的main方法


image.png
org.apache.spark.deploy.yarn.ApplicationMaster

會根據(jù)運行模式(client or cluster), 這里是client模式,所以執(zhí)行runExecutorLauncher

image.png
image.png
image.png
image.png
image.png

通過ExecutorRunnable來啟動Executor

image.png

ExecutorRunnable中有nmClient, 就是NodeManagerClient, 通過nmClient與NodeManager RPC通信, 啟動Executor


image.png

prepareCommand會指定Executor所啟動的類


image.png

這個類就是CoarseGrainedExecutorBackend, 并且會傳入driver url,


image.png
Executor 啟動

CoarseGrainedExecutorBackend也是一個EndPoint,所以也會走RPC的生命周期方法,一個很重要的點是,Client -> Master->Worker ->Executor將driverUrl的信息傳遞給Executor,Executor啟動后根據(jù)driverUrl向driverUrl反向注冊自己


image.png

Driver接收到Executor注冊后,運算資源已經(jīng)有了,DriverEndpoint里的開始調度,如果有Task,就開始LaunchTask,到此,Spark On Yarn Client源碼分析完畢

image.png

接下來分析 Yarn Cluster模式

Yarn Cluster 總架構

Cluster與Client不同的是,Client的Driver(分配Task)和ApplicationMaster(申請資源)是不在同一個進程里面的,Cluster模式的Driver(分配Task)和ApplicationMaster(申請資源)不同一個進程里

image.png

由SparkSubmit圖我們可以知道,Cluster模式里,啟動的是YarnClusterApplication

YarnClusterApplication

image.png

org.apache.spark.deploy.yarn.Client

這個是和 client 模式中使用同樣的Client類,不同的是,cluster啟動的是org.apache.spark.deploy.yarn.ApplicationMaster, 前面我們分析知道client模式中org.apache.spark.deploy.yarn.ExecutorLauncher 其實就是調用了ApplicationMaster.main(), 還有一點是cluster模式中,需要啟動driver

image.png
ApplicationMaster
image.png
runDriver

在ApplicationMaster進程中,通過反射調用userClass, userClass中就會啟動SparkSession, SparkContext等.


image.png
image.png

分析源碼可以得到下面這個圖,本質上還是用的CoarseGrainedExecutorBackend里的driver

image.png
ApplicationMaster里的資源申請(啟動Executor)

邏輯和client分析過程一樣的,就是通過ExecutorRunnable啟動CoarseGrainedExecutorBackend


image.png

Yarn Cluster 總架構

image.png

總結

本文從源碼,分析Yarn模式下Client&Cluster模式的資源啟動流程,分析Client&Cluster究竟有什么不一樣,本質的不一樣就是Driver和ApplicationMaster在不在同一進程里。
本文如果有錯誤的地方,歡迎指出。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容