【Spark2.0源碼學習】-8.SparkContext與Application介紹

         在前面的內容,咱們針對於RpcEndpoint啓動以及RpcEndpoint消息處理機制進行了詳細的介紹,在咱們的大腦裏,基本上能夠構建Spark各節點的模樣。接下來的章節將會從Spark如何從業務代碼分解爲Spark的任務,並最終調度這些任務進行詳細的介紹。
 
     前面針對於Client啓動過程以及Driver進行了詳細的描述,下面咱們根據用戶代碼中的SparkContext這個API類進行解讀,該類Spark用戶代碼執行的基礎,後續咱們會陸續介紹,下面針對於SparkContext以及SparkContext運行過程當中產生的Application進行介紹。
 
1、SparkContext建立過程
SparkContext在新建時
  • 內部建立一個SparkEnv,SparkEnv內部建立一個RpcEnv
    • RpcEnv內部建立並註冊一個MapOutputTrackerMasterEndpoint(該Endpoint暫不介紹)
  • 接着建立DAGScheduler,TaskSchedulerImpl,SchedulerBackend
    • TaskSchedulerImpl建立時建立SchedulableBuilder,SchedulableBuilder根據類型分爲FIFOSchedulableBuilder,FairSchedulableBuilder兩類
  • 最後啓動TaskSchedulerImpl,TaskSchedulerImpl啓動SchedulerBackend
    • SchedulerBackend啓動時建立ApplicationDescription,DriverEndpoint, StandloneAppClient
    • StandloneAppClient內部包括一個ClientEndpoint
 
2、 SparkContext簡易結構與交互關係
     
  • SparkContext:是用戶Spark執行任務的上下文,用戶程序內部使用Spark提供的Api直接或間接建立一個SparkContext
  • SparkEnv:用戶執行的環境信息,包括通訊相關的端點
  • RpcEnv:SparkContext中遠程通訊環境
  • ApplicationDescription:應用程序描述信息,主要包含appName, maxCores, memoryPerExecutorMB, coresPerExecutor, Command(
    CoarseGrainedExecutorBackend),  appUiUrl等
  • ClientEndpoint:客戶端端點,啓動後向Master發起註冊RegisterApplication請求
  • Master:接受RegisterApplication請求後,進行Worker資源分配,並向分配的資源發起LaunchExecutor指令
  • Worker:接受LaunchExecutor指令後,運行ExecutorRunner
  • ExecutorRunner:運行applicationDescription的Command命令,最終Executor,同時向DriverEndpoint註冊Executor信息
 
3、 Master對Application資源分配
     當Master接受Driver的RegisterApplication請求後,放入waitingDrivers隊列中,在同一調度中進行資源分配,分配過程以下:
     
     waitingApps與aliveWorkers進行資源匹配
  • 若是waitingApp配置了app.desc.coresPerExecutor:
    • 輪詢全部有效可分配的worker,每次分配一個executor,executor的核數爲minCoresPerExecutor(app.desc.coresPerExecutor),直到不存在有效可分配資源或者app依賴的資源已所有被分配
  • 若是waitingApp沒有配置app.desc.coresPerExecutor:
    • 輪詢全部有效可分配的worker,每一個worker分配一個executor,executor的核數爲從minCoresPerExecutor(爲固定值1)開始遞增,直到不存在有效可分配資源或者app依賴的資源已所有被分配
  • 其中有效可分配worker定義爲知足一次資源分配的worker:
    • cores知足:usableWorkers(pos).coresFree - assignedCores(pos) >= minCoresPerExecutor,
    • memory知足(若是是新的Executor):usableWorkers(pos).memoryFree - assignedExecutors(pos) * memoryPerExecutor >= memoryPerExecutor
  • 注意:Master針對於applicationInfo進行資源分配時,只有存在有效可用的資源就直接分配,而分配剩餘的app.coresLeft則等下一次再進行分配
 
4、 Worker建立Executor
     
(圖解:橙色組件是Endpoint組件)
    Worker啓動Executor
  • 在Worker的tempDir下面建立application以及executor的目錄,並chmod700操做權限
  • 建立並啓動ExecutorRunner進行Executor的建立
  • 向master發送Executor的狀態狀況
    ExecutorRnner
  • 新線程【ExecutorRunner for [executorId]】讀取ApplicationDescription將其中Command轉化爲本地的Command命令
  • 調用Command並將日誌輸出至executor目錄下的stdout,stderr日誌文件中,Command對應的java類爲CoarseGrainedExecutorBackend
    CoarseGrainedExecutorBackend
  • 建立一個SparkEnv,建立ExecutorEndpoint(CoarseGrainedExecutorBackend),以及WorkerWatcher
  • ExecutorEndpoint建立並啓動後,向DriverEndpoint發送RegisterExecutor請求並等待返回
  • DriverEndpoint處理RegisterExecutor請求,返回ExecutorEndpointRegister的結果
  • 若是註冊成功,ExecutorEndpoint內部再建立Executor的處理對象
 
   至此,Spark運行任務的容器框架就搭建完成
相關文章
相關標籤/搜索