SparkSubmit 提交作业源码流程粗略概述(含application中 driver、client、 executor的创建)

SparkSubmit 提交作业源码流程及作业中 driver、client、 executor的创建

源码基于1.5.1版本,流程是自己阅读源码加网上前人的文章学习总结的,可能存在差错,恳请指正。

大体流程说明: (后续作补充修改)
1、通过 sparkSubmit 命令提交执行SparkSubmit的main函数,
2、在SparkSubmit的main函数中调用 prepareSubmitEnvironment 方法,这个方法用于解析当前用户作业提交命令中包含的集群管理器和Driver部署模式,以及命令参数,对环境进行解析
3、环境解析完成后,执行runMain()函数;因为standalone-cluster模式,master以spark开头并且deploy-mode为cluster,因此,mainClass是org.apache.spark.deploy.Client
4、进入到org.apache.spark.deploy.Client的main函数。Client类用于在Standalone-Cluster模式下启动和停止Driver
5、在org.apache.spark.deploy.Client的main函数中创建 ClientEndpoint ,这是一个Akka的Actor,定义于org.apache.spark.deploy.Client 类中
6、ClientEndpoint 执行它的 onStart 方法,主要工作是封装Driver信息,给Master发送 RequestSubmitDriver 请求,请求参数是 DriverDescription
命令提交job后 调用 SparkSubmit.main()

SparkSubmit.main()
=> submit(args: SparkSubmitArguments)
{
    val (childArgs, childClasspath, sysProps, childMainClass) = prepareSubmitEnvironment() // 获取系统参数 mainClass 等
    {
        if (args.isStandaloneCluster) { // 如果是 Standalone 模式
            if (args.useRest) {  // 如果是 rest 提交
                childMainClass = "org.apache.spark.deploy.rest.RestSubmissionClient"
            }else{         // 不是 rest 提交
                childMainClass = "org.apache.spark.deploy.Client"
            }
        }
    }
    runMain()
    {
        mainClass = Utils.classForName(childMainClass)
        val mainMethod = mainClass.getMethod("main", new Array[String](0).getClass)
        mainMethod.invoke(null, childArgs.toArray) // 调用 childMainClass 的 main 方法
    }
}

在org.apache.spark.deploy.Client 内

org.apache.spark.deploy.Client
{
    main()
    {
        val rpcEnv = RpcEnv.create("driverClient", ...)
        val masterEndpoints = driverArgs.masters.map(RpcAddress.fromSparkURL).map(rpcEnv.setupEndpointRef(Master.SYSTEM_NAME, _, Master.ENDPOINT_NAME))
        // 创建 ClientEndpoint ,即 Client 端, 随即会调用 Client.ClientEndpoint.onStart() 向Master发送 RequestSubmitDriver 请求注册启动 driver
        rpcEnv.setupEndpoint("client", new ClientEndpoint(rpcEnv, driverArgs, masterEndpoints, conf))
    }
}

new ClientEndpoint(..)后会自动调用Client.ClientEndpoint中onStart() 方法,方法后流程如下:

=> 向 Master 发送 RequestSubmitDriver 消息
=> Master 调 receiveAndReply() 
=> Master 构建 driver 描述,调 schedule() 向 Worker 发送 launchDriver 消息  ; (这里不执行 excutor 的建立)
=> Worker 启动 driver 进程, process = Some(command.start())

driver 进程内:

=> driver 进程内执行 application 中main方法,即执行所编写的代码
=> new SparkContext()
    => backend = new SparkDeploySchedulerBackend() 
    => 创建 taskScheduler 、 dagScheduler
    => taskScheduler.start => backend.start() 
        {    
            driverEndpoint = rpcEnv.setupEndpoint()
            client = new AppClient() => client.start()
            {
                new ClientEndpoint() 其 onStart()方法 向 Master 发送 RegisterApplication 请求
                    => Master 端 receive() 执行 schedule() 
                        => schedule() 内 启动各 Excutor  (这里不执行 driver 的通知建立)
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值