(八)Spark源碼理解之DAGScheduler---part3

講講自己對於ShuffleMapTaskResultTask的區別
    簡單來說兩者都是Task類的子類,不同的是操作類型,前者的操作類型是MapStaus類,是在shuffle map stage生成的,後者的操作類型是數據,是在final stage生成的,多說一句,所謂的Spark基於內存存儲中間數據應該就是存儲MapStatus(分區的映射狀態),鑑於它們都是Task類的子類,因此對Task類的核心方法----runTask方法進行簡單講述下
Shuffle map task首先生成和該任務相關的BlockObjectWriter對象,BlockObjectWriter用來將分區寫入磁盤中,這就和之前提到的BlockManager的內容扯上了關係,之後根據生成的BlockObjectWriter對象得到任務的壓縮大小,最後將BlockManagerId和任務的壓縮大小封裝在MapStatus對象中,存儲MapStatus即可,該MapStatus對象又會作爲其他shuffle map stage的輸入,緊接着Shuffle map task會調用TaskContext類的executeOnCompleteCallbacks()函數,執行存儲在onCompleteCallbacks數組緩存中的函數,這些函數就是我們應用程序中所涉及到的函數,在我們每生成一個任務的過程時,該任務的TaskContext對象就會將在這個過程中應用到的函數(我覺得這些函數就是我們應用程序中所編寫的函數)添加到onCompleteCallbacks中
而ResultTask的runTask過程就相對來說比較易於理解,因爲ResultTask不牽涉shuffle過程,它是一個job的最後階段,一個job只會有一個ResultTask,在runTask()方法中首先ResultTask執行傳遞給finalStage的函數func(因爲resultTask只會在finalStage中生成),之後ResultTask會調用TaskContext類的executeOnCompleteCallbacks()函數,其實關於ShuffleMapTask和ResultTask我的理解始終有所模糊,不過暫且理解如下,希望日後能夠得到更進一步的理解
 
    通過上面的講述,我認爲整個stage或者任務的提交應該都是基於job的提交,只有job提交後才能進行stage的劃分,任務集的提交,任務的執行,因此接下來講講DAGScheduler中的job提交部分,這部分結束之後纔算得上是完成了整個spark的調度過程
應用程序中RDD有許多的動作函數,如collect()等,在前面RDD章節中已經介紹過了,正是由於這些動作函數,觸發了job的提交,進而觸發了整個調度過程,可以藉助下圖進行理解:

其中:finalStage是一個Stage類的對象,它通過newStage()方法生成,是整個job過程的最後一個stage
之後的步驟就可參照上述DAGScheduler劃分stage的那部分了,如此就基本上完成了整個DAGScheduler的調度過程
   在之前的章節中已經對submitStage等方法做了解釋,現在稍微講述下runLocally()方法的實現思想
runLocally()方法是在finalStage沒有父stage,且允許本地運行,同時RDD只有一個分區的情況下才會調用,它生成一個線程對象(Thread),並且重寫了Thread類的run方法(即調用DAGScheduler中的runLocallyWithinThread()方法,該方法就是生成一個TaskContext類對象,之後執行觸發這個job的動作函數,動作函數的參數即爲剛剛生成的TaskContext類對象以及其他),之後讓線程start(即允許重寫的run()方法)即可
   DAGScheduler中還有其他方法,基本上就是用於處理各種事件,如任務集失敗等等,這可以聯想到之前講TaskSetManager時提到過TaskSetManager用來處理各種任務集所發生的事件時就是調用DAGScheduler的相應方法,在這裏就不繼續講下去了,點到爲止,我主要是想搞明白DAGScheduler如何劃分stage以及如何提交任務集給TaskScheduler,因此這部分就講到這裏,雖然還有很多講得不太清楚的地方,因此希望可以通過日後的學習及運用加深理解
未完待續。。。
PS:覺得楷體不太適合博文。。換種試試。。。


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