1.启动Spark集群
2.执行jar包
3.启动了Driver进程(通过执行代码启动了Driver) 然后生成了两个对象DSGSchedule TASKSchedule
4.当TaskSchedule创建完成之后向master发送一个请求:为当前的Application申请资源。申请多少资源是有默认值的,或者配置值如下
5.Master接受了资源请求后,根据自己所管理的资源情况,会通知资源充足的Worker节点上启动Executor进程
6.Master向worker发送消息:在你的节点上启动Executor 启动什么样子的Executor也在这个消息里告诉(此时所有的Executor全部启动起来)
7.每一个Executor进程启动完毕后都会反向注册给TASKSchedule(当第7步完事儿后 TaskSchedule就有一批Executor地址)
(3.4.5.6.7是第二行代码触发的)
8.(然后第三行代码)当遇到count算子时候会触发job的执行,DAGSchedule根据RDD宽窄依赖切割job,划分stage,stage内部的rdd一定是窄以来,stage与stage之间是宽依赖,切割完毕后DAGSchedule会将这个stage中所有的task封装到taskSet对象中然后发送给TaskSchedule。(发送指的是DAGSchedule调用了TaskSchedule的一个submittask方法)
9.taskSchedule接受到每一个TaskSet对象后,都会遍历这个TaskSet集合,将集合中每一个task发送到Executor中执行。
补充 TaskSchedule 在发送每一个task之前,首先要看一下要计算数据的位置。
Spark可以复用资源(Executor)这是由于Spark粗粒度资源调度导致
而MR这种细粒度资源调度计算框架,只要上一个Action算子执行完毕后启动的Executor会被kill掉。
注意:如果想让你的Application分布式计算,那么你的代码中就不要设置conf,setMsater为local,干脆不用设置
并且在提交Application的时候要指定--master这个选项以及选项参数(spark://hadoop1:7077)