图是官方图,解释为本人理解,如果错误,望指出!
Spark yarn
yarn-client
- 1、首先是各个NM节点向ResourceManager汇报资源情况,等待被分配,调用
- 2、客户端提交任务申请,会在当前客户端启动一个Driver,然后向RS申请,启动 AM
- 3、RS收到申请,会随机选择一台NM(节点)启动AM。
- 4、AM启动之后,会向RS申请一批资源,用来启动Executor
- 5、RS收到请求,会找到一批NM,返回给AM
- 6、AM拿到资源之后,会去连接NM,然后启动Executor
- 7、Executor启动会,会反向注册给Driver,由Driver发送task到Executor
- 8、最后,Executor会将执行情况和结果返回给Driver
补充:提交的节点就是Driver,本身还是有AM,但是任务的调度归属于Driver
yarn-cluster
- 1、首先是各个NM节点向ResourceManager汇报资源情况,等待被分配,调用
- 2、客户端提交任务申请,向RS申请,请求启动 AM
- 3、RS收到请求后,在集群随机找一台NM节点,启动AM
- 4、当AM启动后(相当于Driver,因为把他们合二为一了),向RS申请一批资源,用来启动Executor
- 5、RS收到请求后,返回一批NM给AM AM 拿到这一批NM 会先连接到AM,然后启动Executor
- 6、Executor启动后,会反向注册到AM所在节点上的Driver,然后由这个Driver来给Executor发送task
- 7、最后,Executor会将执行情况和结果返回给Driver
补充:Driver和AM二合一 AM -->负责任务调度
client模式和cluster模式的区别
client
模式提交任务,会在客户端看到task的执行情况和结果,当在客户端提交多个application时,每个application都会启动自己的Driver,Driver与集群Worker有大量的通信,会造成客户端网卡流量激增问题。这种模式适用于程序测试。不适用于生产环境。cluster
模式提交任务,Driver会在急群众随机一台Worker上启动,如果提交多个application时,那么每个application的Driver会分散到集群的Worker节点,相当于将client模式的客户端网卡流量激增问题分散到集群中。这种模式适用于生产环境。- 补充:因为cluster模式,随机分散在Worker节点上创建Driver,由Driver来发送任务到Worker。所以打包的程序任务必须在分散的Worker节点对应的目录下都存在
spark 任务调度流程 -->相当于集群启动之后 对单个任务的调度
- 1、启动集群之后,worker节点会向Master节点汇报资源情况,Master掌握了集群资源情况
- 2、当spark提交任务申请后,会根据RDD之间的依赖关系,生成DAG
- 3、任务提交后,Spark会在Driver端创建两个对象:DAGScheduler 和 TaskScheduler
DAGScheduler 是任务调度的高层调度器,是一个对象 - 4、DAGScheduler 会讲DAG根据RDD之间的宽窄依赖关系划分为一个个的Stage,然后这些Stage以TaskSet的形式提交给TaskScheduler
(TaskScheduler 是任务调度的底层调度器,这里的TaskSet 其实是一个封装了多个task任务的集合,也就是stage中的并行的task任务) - 5、TaskScheduler会遍历TaskSet集合,拿到每个task 并将他们发送到Executor中去执行
(其实就是发送到Executor中的线程池 ThreadPool 去执行) - 6、task在Executor线程池中的运行情况会向TaskScheduler 反馈,当task执行失败时, 则由TaskScheduler 负责重试(将task重新发送给executor去执行),默认重试三次,如果重试三次依然失败,那么,这个task所在的stage 就失败了
- 7、stage失败了则由DAGScheduler来负责重试,重新发送TaskSet到TaskScheduler(Stage默认重试四次),如果重试四次以后依然失败,那么,这个job就失败了。job失败了,本次的任务申请也就失败了(一次任务申请 就是一个job)
- 8、补充:
推测执行机制
TaskScheduler 不仅能重试失败的task,还会重试 straggling(运行缓慢,落后太多的task)。
会由TaskScheduler启动一个新的task来与这个运行缓慢的task执行一样的处理逻辑,两个相同的task 哪个先执行完,就以哪个task的执行结果为准。
在Spark中 推测执行机制默认关闭,可以通过spark.speculation属性来配置 开启。