1> 将我们编写好的代码打成jar包,提交到集群上运行。
2> 执行spark-submit脚本
3> 调用sparkSubmit这个类的main方法,在main方法中通过反射的方式,
创建我们自己spark作业的主类实例对象。
然后调用main方法,开始执行我们自己写的代码。
4> 开始初始化sparkContext对象,在初始化sparkContext对象时会创建
两个重要的对象(DAGScheduler,TaskScheduler)
5> 将请求参数封装成ApplicationDescription对象,向master进行任务
的注册。
6> master接受到driver的clientActor的注册请求时,会将请求参数进
行封装,封装成app,然后加入到master的任务队列中。
7> 加入到队列后,将app进行持久化
8> 当轮到我们提交任务开始执行时,会调用scheduler()这个方法,
进行任务调度和资源分配。
9> master将分配好的资源封装到launchExecutor中,
发送到指定的worer上。
10> worker接收到master发送过来的LaunchExecutor时,
将其解析并封装到ExecutorRunner中。
11> 调用Executor的start方法,在这个方法中,创建了一个线程,
在这个线程的run方法中启动了一个用于执行任务的容器(进程)
12> executor启动成功后向DriverActor反向注册。
13> 发送反向注册成功的消息
14> 接收到driverActor发送过来的注册成功的消息后,会创建一个线程池,
这个线程池用于执行driverActor发送过来的任务。
15> 当属于这个任务的所有Executor都反向注册成功后,Driver会结束
sparkContext对象的初始化,继续运行我们自己编写的代码。
16> driver端结束sparkContext初始化工作后,开始执行我们编写的代码。
然后开始创建rdd的依赖关系,当遇到一个action算子时,就意
味着触发一个job,然后driver会将这个job提交给DAGScheduler
17> DAGscheduler接收到这个Job时,开始对着job的rdd依赖关系进行划分,
划分成一个一个stage,然后将stage封装成taskSet,
提交给DriverActor。
18> 将taskSet发送给DriverActor
19> DriverActor接收到dagScheduler发送过来的taskSet时,开始对
taskSet中的每个task进行序列化,然后将序列化好的task封装成
LaunchTask,发送给指定的executor
20> executor接收到driverActor发送过来的launcuTask时,会将其解
析并封装到RunnerTask中,然后从线程池中获取一个线程,
进行反序列化。然后执行我们编写的算子。将这些算子作用在其保存
的rdd的分区上。
|
|