(七)Spark源碼理解之TaskScheduler----part6

恩。。。。由於最近這段時間都在實習以及找工作,因此就將博客給落下了,現在繼續將spark的部分"搬上"。。PS:雖然我自己也忘得差不多了。。

4.Executor

Executor類完成任務的裝載,任務的運行等功能,它有個變量爲ExecutorSource對象,這個對象主要實現註冊executor的各項資源,在此省略不講,此外Executor類有個核心方法launchTask(),該方法在之前的過程也稍微提到了,在此貼出其代碼做詳細的介紹

def launchTask(context: ExecutorBackend, taskId: Long, serializedTask:ByteBuffer) {
    val tr = new TaskRunner(context, taskId, serializedTask)//生成TaskRunner類,之後會詳細介紹
    runningTasks.put(taskId, tr)//將任務放在正在運行任務的容器中,進行標記
    threadPool.execute(tr)//threadPool爲ThreadPoolExecutor類,用來執行任務,這也和之前我們說過的任務是利用線程來執行的是一致的,關於線程這一部分我基本上看了下代碼很複雜,頭大大了,涉及到Worker類等等,不過最終是調用TaskRunner的run()方法執行任務的
  }

4.1 TaskRunner

TaskRunner(execBackend: ExecutorBackend, taskId: Long,serializedTask: ByteBuffer)是Executor中比較重要的一個類,它主要完成執行任務的功能,實現這一功能主要是依靠它的run()方法,因此關於TaskRunner我主要講述下run方法,因run方法的代碼略長,就不貼出來了,講下它的基本過程:

獲得當前時間作爲startTime---->設置spark環境,獲得序列器ser---->調用ExecBackend對象的statusUpdate方法更新任務的狀態爲運行--->設置taskStart爲0,其作用在後述步驟中會提到--->清空累加器----->獲得該任務的反序列化對象(該對象包含任務的文件,JAR包,以及任務本身),之後利用獲得信息更新任務的文件,JAR包內容---->將進行上述操作之後的當前時間賦值給taskStart(我覺得這裏有點不好,其實可以直接在這裏聲明taskStart,前面就可以不用聲明瞭),作爲在做好各項準備之後任務真正運行的開始時間----->調用Task類的run方法運行任務(實際上run()方法中調用了runTask()方法),獲得value值,計算當前時間賦值給taskFinish---->將value值序列化爲ByteBuffer---->更新該任務的各項指標(task.metrics),如主機名,任務運行時間等等--->處理該任務的結果(首先將該任務的value值加入到累加器中,與其他任務的value值進行merge--->生成一個DirectTaskResult對象,該對象包含了任務的value值和累加器的值--->序列化DirectTaskResult對象,若其大小超過了一定的限制,則將task轉換爲相應的TaskResultBlockId對象,之後調用BlockManager的putBytes將其存儲在block中(之後會生成對應block的IndirectTaskResult對象,接着序列化該對象,這個對象就作爲最終的任務結果),否則任務結果就爲這個DirectTaskResult對象,不用存儲在block中了,直接傳送給應用程序)----->更新任務狀態爲完成Finished---->若前面的步驟出現異常,則處理各項異常錯誤,將任務從executor類中的runningTasks容器中移除(其添加過程在executor的launchTask方法中出現)

PS:Task有兩種類型:ResultTask和ShuffleMapTask,run()方法最終調用的還是Task的runTask()方法,Task的兩種類型分別有具體的runTask()實現方法

任務運行後會得到相應的任務運行的狀態,如完成,失敗等等,這個時候就又會調用DAGScheduler來處理各種相應事件,因此可以簡要地說調度順序爲DAGScheduler----->TaskScheduler----->DAGScheduler

4.2 ExecutorBackend

ExecutorBackend即爲executor的後臺支撐服務,它有許多的實現方式(子類),即CoarseGrainedExecutorBackend,LocalBackend等

至此關於TaskScheduler的部分已經完成,下面總結下TaskScheduler是如何實現任務調度的,其中各個方法在上述已經詳細介紹,可以參考上述介紹進行理解


未完待續。。。



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