SparkContext内部执行流程
SparkContext内部执行的时序图
对于这个时序图的具体描述如下:
1.SparkSubmit在main()方法中执行,然后根据提交的类型调用相应的方法,这里是”Submit”,调用submit()方法,submit()里面进行一些判断后,
使用反射Class.forName(childMainClass, true, loader),然后调用invoke()方法来调用程序员自己写的类,我们这里是WordCount。
2.在WordCount类中,main()方法里有调用SparkContext,SparkContext构造器使用createSparkEnv()方法,
这个方法使用SparkEnv.createDriverEnv(conf, isLocal, listenerBus)方法创建SparkEnv对象;
在SparkEnv类,调用create()方法来进行创建SparkEnv,在这个方法内部,有一个
AkkaUtils.createActorSystem(actorSystemName, hostname, port, conf, securityManager)的调用过程,
主要用来产生Akka中的ActorSystem以及得到绑定的端口号。
3.在创建SparkEnv对象后,SparkContext构造器使用代码SparkContext.createTaskScheduler(this, master)创建TaskScheduler对象,
这里根据实际的提交模式来进行创建TaskScheduler对象,提交模式有:local、Mesos、Zookeeper、Simr、Spark,
这里模们主要分析Spark集群下的模式;然后还需要创建一个SparkDeploySchedulerBackend对象;
在创建TaskScheduler对象调用initialize()方法,这里选择调度模式,主要有两种模式,FIFO和FAIR,默认的调度模式;
最后调用taskScheduler的start()方法,里面主要调用SparkDeploySchedulerBackend对象的start()方法,
首先调用父类的start()方法产生一个用于和Executor通信的DriverActor对象,然后里面主要创建一个AppClient对象内部有ClientActor类对象,
用于Driver和Master进行RPC通信。
SparkContext源码分析流程
1.SparkSubmit半生对象的源码
1.1SparkSubmit的main()函数在SparkSubmit半生对象的104行左右,这个是程序的主要入口:
//TODO 程序执行的主入口,然后根据提交参数的类型进行模式匹配
def main(args: Array[String]): Unit = {
val appArgs = new SparkSubmitArguments(args)
if (appArgs.verbose) {
printStream.println(appArgs)
}
//TODO 进行模式匹配,这里主要看submit用例类
appArgs.action match {
case SparkSubmitAction.SUBMIT => submit(appArgs)
case SparkSubmitAction.KILL => kill(appArgs)
case SparkSubmitAction.REQUEST_STATUS => requestStatus(appArgs)
}
}
接下来主要进入submit()方法,下面是submit()方法
1.2SparkSubmit的submit()方法,代码大约在142行左右, 这个方法的主要作用是根据不同的模式使用runMain()方法:
private[spark] def submit(args: SparkSubmitArguments): Unit = {
val (childArgs, childClasspath, sysProps, childMainClass) = prepareSubmitEnvironment(args)
def doRunMain(): Unit = {
if (args.proxyUser != null) {
val proxyUser = UserGroupInformation.createProxyUser(args.proxyUser,
UserGroupInformation.getCurrentUser())
try {
proxyUser.doAs(new PrivilegedExceptionAction[Unit]() {
override def run(): Unit = {
runMain(childArgs, childClasspath, sysProps, childMainClass, args.verbose)
}
})
} catch {
case e: Exception =>
// Hadoop's AuthorizationException suppresses the exception's stack trace, which
// makes the message printed to the output by the JVM not very