我这里以standalone-client模式为例。。。。。。。

1.资源调度

①Worker向Master汇报资源
②Master掌握集群的资源
③new SparkContext(conf)在Driver创建DAGScheduler对象和TaskSchedule对象
④TaskSchedule向Master申请资源
⑤Master收到请求后,找到满足资源的节点,启动Executor
⑥Executor启动之后反向注册给TaskSchedule,Driver掌握一批资源

2.任务调度

⑦当遇到Action算子时,会生成一个job,job中RDD依赖关系形成DAG(有向无环图)提交给DAGScheduler
⑧DAGScheduler拿到每个job中的RDD依赖关系形成的DAG有向无环图,依照RDD的宽窄依赖切割job划分stage,将stage封装成TaskSet对象提交给TaskSchedule
⑨TaskSchedule会遍历TaskSet拿到一个个的task,发送到Executor中的ThreadPool中去执行
⑩发送task到ThreadPool中
⑪TaskSchedule监控task执行回收结果

注: Spark任务的运行是先由Application去调度资源然后在执行任务的一种粗粒度资源申请模式

  • 流程图

注:

task在Executor线程池中的运行情况会向TaskScheduler反馈,当task执行失败时,则由TaskScheduler负责重
试,将task重新发送给Executor去执行,默认重试3次。如果重试3次依然失败,那么这个task所在的stage就失败了。
stage失败了则由DAGScheduler来负责重试,重新发送TaskSet到TaskSchdeuler,Stage默认重试4次。如果重试4
次以后依然失败,那么这个job就失败了。job失败了,Application就失败了,当一个Application中有多个
job任务时,在失败job之前的job都执行完成,执行结果会被保留下来,在失败job后的job都不会再执行,整个
Application就失败了。

推测执行机制

TaskScheduler不仅能重试失败的task,还会重试straggling(落后,缓慢)task(也就是执行速度比其他task慢太多的task)。如果有运行缓慢的task那么TaskScheduler会启动一个新的task来与这个运行缓慢的task执行相同的处理逻辑。两个task哪个先执行完,就以哪个task的执行结果为准。这就是Spark的推测执行机制。在Spark中推测执行默认是关闭的。推测执行可以通过spark.speculation属性来配置。

注意:
对于ETL类型要入数据库的业务要关闭推测执行机制,这样就不会有重复的数据入库。
☆ 如果遇到数据倾斜的情况,开启推测执行则有可能导致一直会有task重新启动处理相同的逻辑,任务可能一直处于处理不完的状态。

粗粒度资源申请和细粒度资源申请

粗粒度资源申请(Spark)

在Application执行之前,将所有的资源申请完毕,当资源申请成功后,才会进行任务的调度,当所有的task执行完成后,才会释放这部分资源。

优点:在Application执行之前,所有的资源都申请完毕,每一个task直接使用资源就可以了,不需要task在执行前自己去申请资源,task启动就快了,task执行快了,stage执行就快了,job就快了,application执行就快了。
缺点:直到最后一个task执行完成才会释放资源,集群的资源无法充分利用。

细粒度资源申请(MapReduce)
Application执行之前不需要先去申请资源,而是直接执行,让job中的每一个task在执行前自己去申请资源,task执行完成就释放资源。

优点:集群的资源可以充分利用。
缺点:task自己去申请资源,task启动变慢,Application的运行就相应的变慢了。