Spark-2.4.0 源碼學習系列《Master的啓動過程》

目錄

一、Master啓動主流程

1.1 Master main方法    

1.2 startRpcEnvAndEndpoint(...)

1.3 rpcEnv.setupEndpoint(...)

二、Master啓動需要注意的地方

2.1 Dispatcher的線程池

2.2 Inbox.process(...)

三、Master的初始化過程

3.1 參數初始化

3.2 Master的onStart()方法 


一、Master啓動主流程

1.1 Master main方法    

    執行 $SPARK_HOME/sbin/start_master.sh 腳本時,執行的是Master.scala中的main方法。下面我們來看代碼,看Master啓動過程中都幹了哪些事:

1.2 startRpcEnvAndEndpoint(...)

    截圖中有註釋,我就不一一說了。我們看重點:startRpcEnvAndEndpoint(...)

1.3 rpcEnv.setupEndpoint(...)

    這裏我們重點看一下第3步: val masterEndpoint = rpcEnv.setupEndpoint(...)

    這個方法需要兩個參數:endPoint的名字,這裏是ENDPOINT_NAME,也就是“Master”,還有一個endPoint對象,也就是Master對象,Master對象就是在此處實例化 的(稍後講解)。

    rpcEnv.setupEndpoint(...)最終調用的是dispatcher.registerRpcEndpoint(name, endpoint),我們來看一下這個方法:

        這裏第4步和第7步需要強調一下:

        第4步:向Dispatcher中註冊EndPoint時,需要傳入一個EndPointData,初始化EndPointData時會創建該EndPoint的Inbox,而InBox的初始化完成後,會向InBox的messages中添加一個OnStart信息(OnStart是InBox處理的第一條信息)。

 org/apache/spark/rpc/netty/Inbox.scala:80

      第7步:向Dispatcher的receviers中添加一個EndPointData,這個data是爲OnStart準備的。

    rpcEnv.setupEndpoint(...)方法執行完後,返回一個endpointRef,Master.scala中的啓動相關的代碼就看完了(Master初始化還沒看),在看Master對象初始化之前我們先回頭看一下Dispatcher。

二、Master啓動需要注意的地方

2.1 Dispatcher的線程池

            還記得Dispatcher的線程池嗎?這裏我們再來看一下:

2.2 Inbox.process(...)

    Dispatcher初始化了一個線程池,並啓動。我們在看一下MessageLoop

    Master的註冊過程中向dispatcher的receivers中添加了一個EndPointData,Inbox中添加了一個OnStart。所以線程運行到if(data == PoisonPill)時,條件不成立,進入第3步,執行data.inbox.process(Dispatcher.this)。我們再來看看這個方法:

     首先取出inbox中的數據,做非空判斷,處理線程數問題。下面開始處理數據:

   我們看一下3.3 OnStart信息的處理。InBox初始化時往messages中添加了一個OnStart,所以Master第一次啓動時,Dispatcher-EndPoint-InBox中存的第一條信息是OnStart。3.2.1調用的onstart()方法即是Master的onStart方法。也就是說,在Master初始化完成後,便開始執行其onStart()方法。

三、Master的初始化過程

    下面我們看一下Master的初始化過程,隨後再看下Master的onStart()方法都幹了哪些事:

    Master是在Master.scala startRpcEnvAndEndpoint(...)方法中向env註冊時通過new關鍵字初始化的。我們直接看Master類有哪些屬性,之後再看其onStart方法。

3.1 參數初始化

    Master初始化時初始化了很多屬性,這裏我們撿幾個重要的列一下:

  // hadoop配置
  private val hadoopConf = SparkHadoopUtil.get.newConfiguration(conf)
  // Worker超時時間,默認60s
  private val WORKER_TIMEOUT_MS = conf.getLong("spark.worker.timeout", 60) * 1000
  // executor最大重試次數(默認10次,也就是說最多執行11次)
  private val MAX_EXECUTOR_RETRIES = conf.getInt("spark.deploy.maxExecutorRetries", 10)
  // worker列表,裏面存放worker的id,地址,端口,核心數,內存,worker引用,webUi地址
  val workers = new HashSet[WorkerInfo]
  // 等待中的apps(已提交未處理)
  private val waitingApps = new ArrayBuffer[ApplicationInfo]
  // app列表
  val apps = new HashSet[ApplicationInfo]
  // 處理完成的apps
  private val completedApps = new ArrayBuffer[ApplicationInfo]
  // 下一個App編號
  private var nextAppNumber = 0
  // 驅動
  private val drivers = new HashSet[DriverInfo]
  // 已完成的driver
  private val completedDrivers = new ArrayBuffer[DriverInfo]
  // Drivers currently spooled for scheduling
  private val waitingDrivers = new ArrayBuffer[DriverInfo]
  // 下一個驅動的編號
  private var nextDriverNumber = 0
  // After onStart, webUi will be set
  private var webUi: MasterWebUI = null
  // master url
  private val masterUrl = address.toSparkURL
  // master weburl
  private var masterWebUiUrl: String = _
  // master節點狀態
  private var state = RecoveryState.STANDBY
  // 如果沒有指定,則默認最大核心數爲Int最大值
  private val defaultCores = conf.getInt("spark.deploy.defaultCores", Int.MaxValue)

3.2 Master的onStart()方法 

    下面我們來看下Master的onstart方法幹了哪些事:

    我們看一下 self.send(CheckForWorkerTimeOut) :

    這個self是RpcEndpointRef,這裏也就是Master的引用,我把實現貼在下面:

    NettyRpcEnv.scala

 

     Dispatcher發送出一條OneWayMessage(不需要回復的)。我們接着往下看:

看一下data.inbox.post(message):

     這時,消息已經存放在Master的inbox中,當Dispatcher的輪詢線程執行到時,會調用inbox.process處理這條消息,inbox.process()方法這裏不再細說(2.1.2),我們直接看對應片段(由dispatcher.postOneWayMessage(message)知道是一條OneWayMessage):

    此處的endpoint.receive即是Master的receive方法,我們看一下:

    Master的receive方法根據接收到的數據類型進行模式匹配,我們看下CheckForWorkerTimeOut數據類型幹了什麼:

    我們看下timeOutDeadWorkers()

 至於worker刪除的細節,這裏就不看了。我們回到Master的onStart方法。

 

    至此,Master的啓動已經完成。我們簡單總結一下:

    首先,初始化了Master rpcEnv環境,初始化了Rpc通信的相關組件,並在Dispatcher和Inbox中添加了啓動數據。初始化一個Master對象,定義了一大堆變量:hadoop配置,worker超時時間、任務恢復模式、worker列表、app列表,驅動、webui等等。之後調用Master的onStart方法,正式啓動Master。

      Master的onStart方法給自己發送了一個CheckForWorkerTimeOut,用於檢查是否有超時的worker,如果有則移除。

    這一篇到這裏吧,以後有新的理解再更新。下一篇我們學習一下Worker的啓動過程。 

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