spark schedulers on driver

application job stage taskSet task 之间的关系是什么

Application:通俗讲,用户每次提交的所有的代码为一个application。
Job:一个application可以分为多个job。如何划分job?通俗讲,出发一个final RDD的实际计算为一个job
Stage:一个job可以分为多个stage。根据一个job中的RDD的依赖关系进行划分
Task:task是最小的基本的计算单位。一般是一个块为一个task,大约是128M

宽窄依赖什么

窄依赖: 父亲RDD的一个分区数据只能被子RDD的一个分区消费:
map, filter, flatMap等
宽依赖:父亲RDD的一个分区的数据同时被子RDD多个分区消费
reduceByKey, groupByKey, coalesce, combineByKey等

DAG调度 - Dependency

DAG调度 – stage调度

调度流程图如下:
在这里插入图片描述

任务调度 – taskset内部task的调度(数据计算本地性级别)

PROCESS_NODE:task的运行和数据在同一个Jvm中
NODE_LOCAL:task的运行和数据在同一台主机中
NO_PREF:task在哪里运行都是一样的快,比如读取mysql
RACK_LOCAL:task的运行和数据在同一机架上
ANY:数据在其他地方,不在同一机架中
尽可能将task调度到最好的本地级别上,因为这样的效率是最高的

任务调度 – taskset内部task的调度(延迟调度配置)

当空闲的Executor上没有需要处理的数据:
1.等待有处理数据的Executor的cpu空闲以运行一个task(延迟调度)
2.立马运行一个本来需要在其他Executor上运行的task
spark.locality.wait.process
spark.locality.wait.node
spark.locality.wait.rack
默认是spark.locality.wait = 3
实际情况中通过调节不同值达到最优的计算分配效果

任务调度 – taskset内部task的调度(推测机制)

推测任务是指对于一个Stage里面拖后腿的Task,会在其他节点的Executor上再次启动这个task,如果其中一个Task实例运行成功则将这个最先完成的Task的计算结果作为最终结果,同时会干掉其他Executor上运行的实例。spark推测式执行默认是关闭的,可通过spark.speculation=true属性来开启。
假设有10个task:
每隔一段时间来检查有哪些正在运行的task需要重新调度:spark.speculation.interval=100ms
成功的task的数量 > 0.75 * 10 spark.speculation.quantile=0.75
正在运行的task的运行时间 > 1.5 * 成功运行task的平均时间 spark.speculation.multiplier=1.5 则这个正在运行的task需要重新等待调度
当正常调度完task之后,再来调度需要重新调度的task
以上配置可以根据实际情况作出调整

任务调度 – taskset内部task的调度(Blacklist机制)

打开黑名单机制: spark.blacklist.enabled=true
spark.scheduler.executorTaskBlacklistTime=100
场景:
1.在很大的集群上跑有很多的stage的spark应用,其中一块硬盘坏了
2.spark应用在很小的集群中失败
3.在很大的集群上跑很少的stage的spark应用
4.坏节点导致很多的shufle fetch失败
5 动态资源分配下有一个节点坏了
Task级别的黑名单:
task的Executor黑名单:一个task在同一个Executor上失败了一定的次数 次数配置:spark.blacklist.task.maxFailuresPerExecutor = 1
task的Host黑名单:一个task在同一个host上有一定数量失败的Executor 数量配置:spark.blacklist.task.maxFailuresPerNode = 2
Stage级别的黑名单:
stage的Executor黑名单:一个stage在同一个Executor上失败了一定数量的task : spark.blacklist.stage.maxFailedTasksPerExecutor = 2
stage的Host黑名单:一个stage在同一个host上有一定数量被标记为task的黑名单Executor:spark.blacklist.stage.maxFailedExecutorsPerNode = 2
Application级别的黑名单(只有taskSet执行成功才会统计计算):
Application的Executor黑名单:一个Executor上有一定数量的失败的task:spark.blacklist.application.maxFailedTasksPerExecutor = 2
Application的Host黑名单:一个host上有一定数量被标记为黑名单的Executor:spark.blacklist.application.maxFailedExecutorsPerNode = 2

备注:
对于每一个黑名单来说,一旦隔了某段时间则解除黑名单:spark.blacklist.timeout = 1h
关于stage可以看webUI的详情,发生宽依赖时就会划分一个,暂时发现flatMapValues除外,因为它已经记住了分区信息

资源调度 - Executor的信息

Executor的RPC引用
Executor的网络地址: spark://host:port
Executor的主机名
Executor中可用的core的数量
Executor中总的core的数量

资源调度 – 资源调度的三大主要功能

资源管理
task的真正launch
task的statusUpdate通知

资源调度 - task的launch

从初始化SparkContext到launch task需要达到一定的规则要求:
1: 注册的Executor的数量达到最小注册比率:
最小注册比例:spark.scheduler.minRegisteredResourcesRatio=0
standalone 和 mesos 要求达到注册的core数量要大于请求的core数量 * 最小注册比率
yarn要求达到注册的executor数量要大于请求的executor数量 * 最小注册比率
2: 如果注册的Executor的数量还没达到要求的最小比例,但是达到了最大的等待时间就可以launch task了
最大等待时间:spark.scheduler.maxRegisteredResourcesWaitingTime=30
3.序列化的task的大小不能超过一定的大小,否则报错
spark.rpc.message.maxSize=128M
4.当一个task被launch到相对应的Executor上时,这个Executor的core数量减少这个task所占有的core数
spark.task.cpus=1
task的launch流程图:
在这里插入图片描述
写个博客,画图太难了,后面的网上找不到图都不画了,太丑了,毕竟我还是新手博主~

资源调度 - task的statusUpdate流程(TaskSetManager成功)

task成功:
1: 将task标记为成功完成
2: 统计task完成的时间,用于其他task的推测机制
3: 将这个task从running状态中移除掉
4: 如果这个task在其他机器上还在执行,则将这个正在执行的task杀掉
5: 统计成功完成task的数量,并判断这个TaskSet中的所有的task是否全部完成
6: 如果这个TaskSet全部完成task,则将这个TaskSet中的失败的task来统计判断黑名单资源
7: 告诉DAGScheduler这个task成功的结果信息
ResultTask
1.更新accumulators
2.判断该task对应的stage是否完成,完成的话则标记完成
3.返回结果
ShuffleMapTask
1.更新accumulators
2.shuffleMapStage将这个task输出数据写入到磁盘中的位置以及数据大小信息记下来
3.判断该task对应的stage是否完成,完成的话则:
1:标记完成
2:将这个shuffleMapstage所有的输出信息注册到mapOutputTracker中,用于shuffle读取数据
3:如果这个stage有失败的task,则需要重新提交这个stage, 否则的话则调度这个stage的子stage

资源调度 - task的statusUpdate流程(TaskSetManager失败)

task失败
1: 将这个task从running状态中移除掉
2: 如果失败原因是FetchFailed,则将这个task标记为成功,但是将对应的TaskSet标记为zombie
3:如果失败的原因是异常,则需要计算是否将异常打印出来
4: 除了FetchFailed,其他的失败原因的task都需要重新调度,达到最大尝试次数为止
5:根据失败的task信息更新相关的黑名单(stage和task级别)
6: 判断taskSet是否完成,如果完成则需要更新application级别的黑名单
FetchFailed
重新提交失败的这个stage以及这个stage对应的ShuffleMapStage

DAG的stage划分逻辑

在这里插入图片描述

多个spark应用的调度 – 动态资源分配机制

申请删除Executor的规则:
如果一个Executor空闲了K秒,则认为这个Executor应该删除掉:spark.dynamicAllocation.executorIdleTimeout=60
如果这个空闲的Executor中含有缓存数据,则需要达到一定的时间后才能删除:spark.dynamicAllocation.cachedExecutorIdleTimeout=Max_value
申请增加Executor的规则:
当有task pending超过一定的时间M后会触发申请增加Executor:spark.dynamicAllocation.schedulerBacklogTimeout=1
当有task pending超过一定的时间N后会触发申请增加Executor,这个时候,申请的Executor数量以指数形式增长(上一次增加的数量 * 2):spark.dynamicAllocation.sustainedSchedulerBacklogTimeout = 1
1: 一开始需要慢慢增长,否则增多了的话,我们需要立马删除这些Executor
2: 再过一段时间需要增加很多,是估计需要大量的Executor,否则的话需要花很长时间来执行大量的任务
开启动态资源分配机制的前提:
将spark.dynamicAllocation.enabled设置为true
将spark.shuffle.service.enabled设置为true
在每一个worker节点上启动external shuffle service

多个spark应用的调度 – External Shuffle Service

在每一个worker节点上启动external shuffle service的方式:
standalone: 将spark.shuffle.service.enabled设置为true

在每一个worker节点中$SPARK_HOME/conf/spark-env.sh中加上:
export SPARK_WORKER_OPTS=-Dspark.shuffle.service.enabled=true
**mesos**: 在每一个slave节点上运行$SPARK_HOME/sbin/start-mesos-shuffle-service.sh 
且将spark.shuffle.service.enabled设置为true
可以使用工具:Marathon

yarn
1: 打出jar包spark--yarn-shuffle.jar 下载spark源码:
在这里插入图片描述
在这里插入图片描述
2: 将spark--yarn-shuffle.jar放到nodeManager的classpath中
3: 配置yarn-site.xml, 如下:

 <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
        <value>spark_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.spark_shuffle.class</name>
        <value>org.apache.spark.network.yarn.YarnShuffleService</value>
    </property>

4: 重启yarn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值