一、構(gòu)造SparkContext

1.1. 在shell下,通過spark-submit命令將Application提交到集群,此時spark會通過反射的方式,創(chuàng)建和構(gòu)造一個DriverActor進程出來(scala中的actor類似java的多線程)
1.2. Driver進程會執(zhí)行我們提交的Application應(yīng)用程序,一般情況下,先構(gòu)造SparkConf,再構(gòu)造SparkContext
1.3. SparkContext在初始化的時候,最主要的做的就是構(gòu)造DAGScheduler和TaskScheduler。
1.4. TaskScheduler實際上,是會負(fù)責(zé),通過它對應(yīng)的一個后臺進程,去連接Spark集群的Master進程注冊Application,
1.5. Master接收到Application的注冊請求后,會使用自己的資源調(diào)度算法(基于調(diào)度器standalone,Yarn,Mesos等都有不同的調(diào)度算法),在Spark集群的Worker上為這個Application啟動Executor
1.6. Master通知worker啟動Executor后,Worker會為Application啟動Executor進程,
1.7. Executor啟動之后,首先做的就是會將自己反向注冊到TaskScheduler上去,到此為止SparkContext完成了初始化。
二、運行Application

2.1. 所有Executor都反向注冊到Driver上之后,Driver結(jié)束SparkContext初始化,會繼續(xù)執(zhí)行我們編寫的代碼
2.2. 每執(zhí)行一個Action就會創(chuàng)建一個job,job會提交給DAGScheduler
2.3 DAGScheduler會采用自己的stage劃分算法將job劃分為多個stage,然后每個stage創(chuàng)建一個TaskSet,在此過程中,stage劃分算法非常重要,后續(xù)會進行詳細(xì)研究。
2.4 DAGScheduler會將TaskSet傳遞給TaskScheduler,TaskScheduler會把TaskSet里每一個task提交到Executor上執(zhí)行(task分配算法)
2.5 Executor每接收一個task都會用TaskRunner來封裝task,然后從線程池里面取出一個線程,執(zhí)行這個task,TaskRunner將我們編寫的代碼,也就是要執(zhí)行的算子以及函數(shù),拷貝,反序列化,然后執(zhí)行Task。
2.6 Task有兩種,ShuffleMapTask和ResultTask。只有最后一個stage是ResultTask,之前的stage,都是ShuffleMapTask.
2.7 所以,最后整個Spark應(yīng)用程序的執(zhí)行,就是將stage分批次作為taskset提交給executor執(zhí)行,每個task針對RDD的一個parktition,執(zhí)行我們定義的算子和函數(shù),以此類推,直到所有操作執(zhí)行完為止。