一、構造SparkContext
1.1. 在shell下,通過spark-submit命令將Application提交到集群,此時spark會通過反射的方式,創建和構造一個DriverActor進程出來(scala中的actor類似java的多線程)
1.2. Driver進程會執行我們提交的Application應用程序,一般情況下,先構造SparkConf,再構造SparkContext
1.3. SparkContext在初始化的時候,最主要的做的就是構造DAGScheduler和TaskScheduler。
1.4. TaskScheduler實際上,是會負責,通過它對應的一個后臺進程,去連接Spark集群的Master進程注冊Application,
1.5. Master接收到Application的注冊請求后,會使用自己的資源調度算法(基于調度器standalone,Yarn,Mesos等都有不同的調度算法),在Spark集群的Worker上為這個Application啟動Executor
1.6. Master通知worker啟動Executor后,Worker會為Application啟動Executor進程,
1.7. Executor啟動之后,首先做的就是會將自己反向注冊到TaskScheduler上去,到此為止SparkContext完成了初始化。
二、運行Application
2.1. 所有Executor都反向注冊到Driver上之后,Driver結束SparkContext初始化,會繼續執行我們編寫的代碼
2.2. 每執行一個Action就會創建一個job,job會提交給DAGScheduler
2.3 DAGScheduler會采用自己的stage劃分算法將job劃分為多個stage,然后每個stage創建一個TaskSet,在此過程中,stage劃分算法非常重要,后續會進行詳細研究。
2.4 DAGScheduler會將TaskSet傳遞給TaskScheduler,TaskScheduler會把TaskSet里每一個task提交到Executor上執行(task分配算法)
2.5 Executor每接收一個task都會用TaskRunner來封裝task,然后從線程池里面取出一個線程,執行這個task,TaskRunner將我們編寫的代碼,也就是要執行的算子以及函數,拷貝,反序列化,然后執行Task。
2.6 Task有兩種,ShuffleMapTask和ResultTask。只有最后一個stage是ResultTask,之前的stage,都是ShuffleMapTask.
2.7 所以,最后整個Spark應用程序的執行,就是將stage分批次作為taskset提交給executor執行,每個task針對RDD的一個parktition,執行我們定義的算子和函數,以此類推,直到所有操作執行完為止。