前面我們講過了了關于spark整體構架原理,在spark中 ,當執(zhí)行我們的application,也就是我們寫的程代碼,我們回想一下,之前我們寫的spark應用的第一行是不是先構造一個sparkConf,接著通過sparkConfs構造一個非常重要的對象:SparkContext
例:val conf = new SparkConf()
val sc = new SparkContext(conf)
通過源碼我們可以得到,在初使化上面SparkContext后,做的最重要的兩件事:
1:構造出DAGScheduler
2:構造出TaskScheduler
在new SparkContext 時,會調用sparkContext中的createTaskScheduler()方法,在這個方法中,批配了好多種提交模式,這里我們以standalone模式為例:
//這就是standland模式
case SPARK_REGEX(sparkUrl) =>
val scheduler = new TaskSchedulerImpl(sc)
val masterUrls = sparkUrl.split(",").map("spark://" + _)
val backend = new SparkDeploySchedulerBackend(scheduler, sc, masterUrls)
scheduler.initialize(backend)
(backend, scheduler)
從上面的源代碼可以看到,做了三件事:
1:新建一個TaskSchedulerImpl對象,其實它就是我們前面說的Taskscheduler
2:創(chuàng)建了SparkDeploySchedulerBackend對象,它在底層會接收TaskScheduler的控制,實際上對Master的控制,Exceutor的反注冊,task發(fā)送executor等操作
3:創(chuàng)建SchedulerPool,它有不用的優(yōu)先策略,比如FIFO
如看下面的源代碼,是在調用了initialize()方法:
接著,會調用TaskSchedulerImpl的start()方法,在這個方法里調用了SparkDeploySchedulerBackend的start()方法,如下:
override def start() {
backend.start()
...}
在這個方法里,創(chuàng)建一個兩個很重要的對象,一個是ApplicationDescription,一個是AppClient,如下:
ApplicationDescription對象是我們提交的應用程序的封裝,AppClient是一個通信對象。接收它創(chuàng)建一個ClientActor對象,這個實際就是一個AKK通信的進程,ClientActor會調用一個叫registerWithMaster()的方法,里面又調用了一個tryRegisterAllMasters()
如下:
RegisterApplication類里封裝了application的描述信息,接著,通信到Master,Master收到請求,向Worker發(fā)出命令啟動Executor來執(zhí)行Application,executor在啟動后反向注冊到SparkDeploySchedulerBackend上去。
spark在初使化的第二個作用是創(chuàng)建DAGScheduler,底層是DAGScheudlerEventProcessActor組件來進行通信的(線程)
第三件事是SparkUI,4040端口,里面是基于一個jetty服務器,提供一個WEB頁面,來顯示application的運行狀態(tài)。