[Spark內核] 第28課:Spark天堂之門解密

 本課主題

  • 什麼是 Spark 的天堂之門
  • Spark 天堂之門到底在那裏
  • Spark 天堂之門源碼鑑賞

 

引言

我說的 Spark 天堂之門就是SparkContext,這篇文章會從 SparkContext 建立3大核心對象 TaskSchedulerImpl、DAGScheduler 和 SchedulerBackend 開始到註冊給 Master 這個過程當中的源碼鑑賞,SparkContext 是整個 Spark 程序通往集羣的惟一通道,它是程序起點,也是程序終點,因此我把它稱之爲天堂之門,看過 Spark HelloWorld 程序的朋友都知道,你在程序的開頭必需先定義SparkContext、接著調用 SparkContext 的方法,好比說 sc.textFile(file),最後也會調用 sc.stop( ) 來退出應用程序。如今咱們就來看看 SparkContext 裏面到底有什麼密碼,以及爲何它會被稱爲天堂之門但願這篇文章能爲讀者帶出如下的啓發:編程

  • 瞭解在 SparkContext 內部建立了那些實例對象以及如何建立
  • 瞭解真正是那個實例對象向 Master 註冊以及如何註冊

 

什麼是 Spark 的天堂之門

  1. Spark 程序在運行的時候分爲 DriverExecutor 兩部分
  2. Spark 程序編寫是基於 SparkContext 的,具體來講包含兩方面
    1. Spark 編程的核心 基礎-RDD 是由 SparkContext 來最初建立的(第一個RDD必定是由 SparkContext 來建立的)
    2. Spark 程序的調度優化也是基於 SparkContext,首先進行調度優化。
  3. Spark 程序的註冊時經過 SparkContext 實例化時候生產的對象來完成的(實際上是 SchedulerBackend 來註冊程序)
  4. Spark 程序在運行的時候要經過 Cluster Manager 獲取具體的計算資源,計算資源獲取也是經過 SparkContext 產生的對象來申請的(實際上是 SchedulerBackend 來獲取計算資源的)
  5. SparkContext 崩潰或者結束的時候整個 Spark 程序也結束啦!

 

Spark 天堂之門到底在那裏

運行一個程序,你會看見 SparkContext 從程序開始到結束都有它的身影,SparkContext 是 Spark 應用程序的核心呀!大數據

[下圖是一個 HelloWord 應用程序在 IDEA 中的運行情況]優化

 

Spark 天堂之門源碼鑑賞

此次主要是看當提交Spark程序後,在 SparkContext 實例化的過程當中,裏面會建立多少個核心實例來爲應用程序完成註冊,SparkContext 最主要的是實例化 TaskSchedulerImpl。spa

[下圖是 SparkContext 在建立核心對象後的流程圖]
線程

  1. SparkContext 構建的頂級三大核心:DAGSchedulerTaskScheduler, SchedulerBackend,其中:
    • DAGScheduler 是面向 Job 的 Stage 的高層調度器;
    • TaskScheduler 是一個接口,是低層調度器,根據具體的 ClusterManager 的不一樣會有不一樣的實現,Standalone 模式下具體的實現 TaskSchedulerImpl; 
    • SchedulerBackend 是一個接口,根據具體的 ClusterManager 的不一樣會有不一樣的實現,Standalone 模式下具體的實現是SparkDeploySchedulerBackend
  2. 從整個程序運行的角度來講,SparkContext 包含四大核心對象:DAGSchedulerTaskScheduler, SchedulerBackend, MapOutputTrackerMaster
  3. SparkDeploySchedulerBackend 有三大核心功能:
    • 負責與 Master 連接註冊當前程序 RegisterWithMaster
    • 接收集羣中為當前應用程序而分配的計算資源 Executor 的註冊並管理 Executors; 
    • 負責發送 Task 到具體的 Executor 執行

補充說明的是 SparkDeploySchedulerBackend 是被 TaskSchedulerImpl 來管理的!scala

建立 SparkContext 的核心對象
  • 程序一開始運行時會實例化 SparkContext 裏的東西,因此不在方法裏的成員都會被實例化!一開始實例化的時候第一個關鍵的代碼是 createTaskScheduler,它是位於 SparkContext 的 Primary Constructor 中,當它實例化時會直接被調用,這個方法返回的是 taskScheduler 和 dagScheduler 的實例,而後基於這個內容又構建了 DAGScheduler,而後調用 taskScheduler 的 start( ) 方法,要先建立taskScheduler而後再建立 dagScheduler,由於taskScheduler是受dagScheduler管理的。
    [下圖是 SparkContext.scala 中的建立 schedulerBackend 和 taskSchdulerImpl 的實例對象]
  • 調用 createTaskSchedule,這個方法建立了 TaskSchdulerImpl 和 SparkDeploySchedulerBackend,接受第一個參數是 SparkContext 對象自己,而後是字符串,(這也是你平時轉入 master 裏的字符串)
    [下圖是 HelloSpark.scala 中建立 SparkConf 和 SparkContext 的上下文信息]

    [下圖是 SparkContext.scala 中的 createTaskScheduler 方法]
  • 它會判斷一下你的 master 是什麼而後具體進行不一樣的操做!假設咱們是Spark 集羣模式,它會:
    [下圖是 SparkContext.scala 中的 SparkMasterRegex 靜態對象]
  • 建立 TaskSchedulerImpl 實例而後把 SparkContext 傳進去; 
  • 匹配集羣中 master 的地址 e.g. spark:// 
  • 建立 SparkDeploySchedulerBackend 實例,而後把 taskScheduler (這裏是 TaskSchedulerImpl)、SparkContext 和 master 地址信息傳進去;
  • 調用 taskScheduler (這裏是 TaskSchedulerImpl) 的 initialize 方法 最後返回 (SparkDeploySchedulerBackend, TaskSchedulerImpl) 的實例對象
  • SparkDeploySchedulerBackend 是被 TaskSchedulerImpl 來管理的,因此這裏要首先把 scheduler 建立,而後把 scheduler 的實例傳進去。
    [下圖是 SparkContext.scala 中的調用模式匹配 SPARK_REGEX 的處理邏輯]
  • Task 默認失敗後從新啓動次數爲 4 次
    [下圖是 TaskSchedulerImpl.scala 中的類和主構造器的調用方法]

TaskSchedulerImpl.initialize( )方法是3d

  • 建立一個 Pool 來初定義資源分佈的模式 Scheduling Mode,默認是先進先出的 模式。

調用 taskScheduler 的 start( ) 方法視頻

  • 在這個方法中再調用 backend (SparkDeploySchedulerBackend) 的 start( ) 方法。

  • 當通過 SparkDeploySchedulerBackend 註冊程序給 Master 的時候會把以上的 command 提交給 Master 

CoarseGrainedExecutorBackend
  • Master 發指令給 Worker 去啟動 Executor 全部的進程的時候加載的 Main 方法所在的入口類就是 command 中的 CoarseGrainedExecutorBackend,當然你能夠實現本身的 ExecutorBackend,在 CoarseGrainedExecutorBackend 中啟動 Executor (Executor 是先註冊再實例化),Executor 通過線程池並發執行 Task。

  • 這裏調用了它的 run 方法


  • 註冊成功後再實例化
SparkDeploySchedulerBackend 的 start 方法內幕
  • 而後建立一個很重要的對象,AppClient 對象,而後調用它的 client (AppClient) 的 start( ) 方法,建立一個 ClientEndpoint 對象。

  • 它是一個 RpcEndPoint,而後接下來的故事就是向 Master 註冊,首先調用本身的 onStart 方法

  • 而後再調用 registerWithMaster 方法

  • 從 registerWithMaster 調用 tryRegisterAllMasters,開一條新的線程來註冊,而後發送一條信息(RegisterApplication 的case class ) 給 Master,註冊是經過 Thread 來完成的。


    ApplicationDescription 的 case class

Master 接受程序的註冊
  • Master 收到了這個信息便開始註冊,註冊後最後再次調用 schedule( ) 方法
     

 

總結

SparkContext 開啓了天堂之門:Spark 程序是經過 SparkContext 發佈到 Spark集羣的SparkContext 導演了天堂世界:Spark 程序運行都是在 SparkContext 爲核心的調度器的指揮下進行的:SparkContext 關閉了天堂之門:SparkContext 崩潰或者結束的是偶整個 Spark 程序也結束啦!對象

 
 

參考資料 

資料來源來至 DT大數據夢工廠 大數據傳奇行動 第28課:Spark天堂之門解密視頻blog

Spark源碼圖片取自於 Spark 1.6.0版本

相關文章
相關標籤/搜索