内容来自尚硅谷
![](https://img-blog.csdnimg.cn/img_convert/28ea94cf47a16d089625e419882cdfd0.png)
1.submitApplication
当spark执行任务时会启动java虚拟机,启动一个进程,该进程的名称为SparkSubmit,会执行SparkSubmit中的main方法,该方法中调用了super.doSubmit方法。
![](https://img-blog.csdnimg.cn/img_convert/2717d2cd50c7ec05dc69f81062537eb4.png)
org.apache.spark.deploy.SparkSubmit
doSubmit方法中首先会解析参数调用parseArguments(args)方法,创建参数构建对象new SparkSubmitArguments(args),根据参数中action类型进行执行,如果是submit就是提交任务
![](https://img-blog.csdnimg.cn/img_convert/7d4826db1216975a3266463573d51e11.png)
2.启动ApplicationMaster
submit方法底层会执行runMain(args, uninitLog),该方法中会调用prepareSubmitEnvironment(args)方法(准备任务提交的环境)
如果是yarn模型,childMainClass=org.apache.spark.deploy.yarn.YarnClusterApplication
![](https://img-blog.csdnimg.cn/img_convert/e6883773689f8fcfb6ddaf414aeb03c0.png)
YarnClusterApplication执行start方法会new一个client对象
![](https://img-blog.csdnimg.cn/img_convert/3eff00df5947390bd7593e4213e4b3ec.png)
client对象中包含yarnClient对象,底层会生成resouceManager对象
![](https://img-blog.csdnimg.cn/img_convert/5fd170b644278ecdb3e3b7daec5a8c06.png)
![](https://img-blog.csdnimg.cn/img_convert/4ff9fa5a974b250973091e92da960232.png)
client.run 会调用submitApplication方法,该方法会封装一些执行的指令
![](https://img-blog.csdnimg.cn/img_convert/77cae8f6b8d73addafdf84d87cbf6d61.png)
该方法中会创建application对象,指定container
![](https://img-blog.csdnimg.cn/img_convert/b6837e83bd8f4cb7b3a9b7b6388e34d9.png)
![](https://img-blog.csdnimg.cn/img_convert/8554da3037e7d6e63a38fcb78935b2c9.png)
当是集群模式是会创建master对象(进程),随后执行run方法,启动Driver
![](https://img-blog.csdnimg.cn/img_convert/5a303a5a1b800d1a3c63403323969877.png)
![](https://img-blog.csdnimg.cn/img_convert/a96d56ad5557de283f5ea744692c7efa.png)
3.启动Driver ,初始化sparkContext
![](https://img-blog.csdnimg.cn/img_convert/46490093bcc5dd79ab7fbeaa33a188be.png)
runDriver中会启动一个线程名字为Driver,并执行提交代码的main方法,执行代码中的new sparkContext(conf)代码
![](https://img-blog.csdnimg.cn/img_convert/8d8ac3da13ef79c10a63dce0bd23ab32.png)
![](https://img-blog.csdnimg.cn/img_convert/a25c3feb09a455277b3a39b2aaab2153.png)
![](https://img-blog.csdnimg.cn/img_convert/277f76c60d240bdf140c92f2becd6c70.png)
4.注册AM,与resouceManage连接申请资源
![](https://img-blog.csdnimg.cn/img_convert/d6975b0e6c9e42662ebd5766118ff1ae.png)
5.注册AM时会获取资源可用服务器链表
![](https://img-blog.csdnimg.cn/img_convert/0562953bf364b9a972dba0ba731653bc.png)
处理可使用的服务器
![](https://img-blog.csdnimg.cn/img_convert/9775dd414608cc9b76f606d2c37de89c.png)
运行已分配服务器
![](https://img-blog.csdnimg.cn/img_convert/15943dbf02b2c42daa66d75eb9a29f0d.png)
6.启动exceutor通信进程
启动executor线程
![](https://img-blog.csdnimg.cn/img_convert/a1d8265c723907919a2fb08c705bf956.png)
执行启动container方法
![](https://img-blog.csdnimg.cn/img_convert/5998e428ddf48fd15933abfcb6f7a432.png)
startContainer首先会封装命令,该命令会启动一个进程(org.apache.spark.executor.YarnCoarseGrainedExecutorBackend executor的通信进程)
![](https://img-blog.csdnimg.cn/img_convert/5e3933474edf130b90dbc4a01d442eab.png)
![](https://img-blog.csdnimg.cn/img_convert/6f9f2939ff8d8c0073131cb78ea1395e.png)
向指定的服务器启动container
![](https://img-blog.csdnimg.cn/img_convert/5227f2b4f46ab6a6f0631214181773e2.png)
创建executorBackend会执行其中的run方法
![](https://img-blog.csdnimg.cn/img_convert/999b702993ff42b67c79c33d65b36ee7.png)
创建SparkEnv环境
![](https://img-blog.csdnimg.cn/img_convert/65c55a5e417ac19e673c678ab91c9691.png)
![](https://img-blog.csdnimg.cn/img_convert/8a66a4e5155988ccc7fcbac61ae967d0.png)
![](https://img-blog.csdnimg.cn/img_convert/e146a545f726ee7c584ae91dff0137aa.png)
![](https://img-blog.csdnimg.cn/img_convert/28b2ff6571a1871df649ac1661bfaa42.png)
![](https://img-blog.csdnimg.cn/img_convert/c8bf1b7fdd9b8da6d4608d0b66560c43.png)
![](https://img-blog.csdnimg.cn/img_convert/0ea1657888b40e0bebc1c65c1a957ddf.png)
7.executor向driver进行注册
onStart方法执行的是CoarseGrainedExecutorBackend中的onStart方法
![](https://img-blog.csdnimg.cn/img_convert/02b0e74aedf727f6e7cfa2c90682e259.png)
当向driver进行注册时,其实是向SparkContext环境进行注册,SparkContext中会有一个对象
![](https://img-blog.csdnimg.cn/img_convert/e85d8cf2ab802cec5a2bec6eeaafddfa.png)
![](https://img-blog.csdnimg.cn/img_convert/da42e7ce885e95b1f7cb8955f72caf5b.png)
服务器端进行接收和回复
![](https://img-blog.csdnimg.cn/img_convert/cbd3de86612ffd4b0f894645c30f70f4.png)
8.executor注册成功
当服务器接收并回复之后,executor会给自己发送消息注册成功
CoarseGrainedExecutorBackend中的onStart方法
![](https://img-blog.csdnimg.cn/img_convert/0f9868b15e39e83a1036e22827168c3b.png)
9.创建executor计算对象
executor当接收到消息后创建executor
![](https://img-blog.csdnimg.cn/img_convert/6790e823bf178fe06bf4a00245dc2aa7.png)
10.执行代码
![](https://img-blog.csdnimg.cn/img_convert/c434acc4a6ebab1e1441b2d530e79ba4.png)
总体
1)执行脚本提交任务,实际是启动一个 SparkSubmit 的 JVM 进程;
2)SparkSubmit类中的main方法反射调用YarnClusterApplication的main方法YarnClusterApplication创建Yarn客户端然后向Yarn服务器发送执行指令: bin/java
ApplicationMaster;Yarn框架收到指令后会在指定的 NM 中启动 ApplicationMaster;
3)ApplicationMaster 启动 Driver 线程,用于执行用户的作业,会创建SparkContext对象,
4)AM中SparkContext对象 向 RM 注册,申请资源;
5) 获取服务器可用列表
6) 获取资源后 AM 向 NM 发送指令: bin/java YarnCoarseGrainedExecutorBackend;
7) CoarseGrainedExecutorBackend 进程会接收消息,跟 Driver 通信
8) 注册已经启动的Executor;
9) sparkContext会解析Application代码,构建DAG图并提交给DAG Scheduler分解成Stage,
stage会提交到Task Scheduler,Task Scheduler负责将Task分配到相应的Worker
8) 然后启动计算对象 Executor 等待接收任务
10) Driver 线程继续执行完成作业的调度和任务的执行。
11) Driver 分配任务并监控任务的执行。
12) 所有Task完成后,SparkContext向Master注销,释放资源