TaskScheduler调度算法与调度池
在DAGScheduer对Stage划分,DAGScheduer将Task提交给TaskScheduler,将多个Task打包为TaskSet后,调用taskScheduler的submitTasks方法。TaskScheduler是一个Trait,在Spark中唯一的实现是TaskSchedulerImpl类,TaskSchedulerImpl用于接收DAGSchduler给每个Stage创建好的TaskSet,按照调度算法将资源分配给Task并且将Task交给Spark集群上Executor运行,当Task失败时进行重试,通过推断执行减轻落后的Task对整体作业进度的影响。
TaskSchedulerImpl中包含一些重要的组件:
1、Pool调度池:TaskSchedulerImpl对任务的调度基于调度池
2、TaskSetManager:用于管理TaskSet,包括任务推断,Task本地性,并对Task的资源进行分配
Pool调度池中有一个根队列rootPool,根队列中包含了多个子调度池,子调度池中还可以包含其他的调度池或TaskSetManager。所以,整个调度池是个多层级的结构。Pool的创建需要四个参数:
1.poolName:调度池名称
2.schedulingMode:调度池模式,共有三种类型:FAIR(公平调度模式)、FIFO(先入先出模式)、NONE
3.initMinShare:MinShare初始值
4.initWeight:Weight初始值
在Pool类中,有一个比较重要的方法taskSetSchedulingAlgorithm。调度池中对taskSet的调度,取决于调度算法,根据调度模式进行匹配。如果是FIFO调度模式,则为FIFO先入先出算法,如果是FAIR调度模式,则为FAIR公平调度算法
var taskSetSchedulingAlgorithm: SchedulingAlgorithm = {
schedulingMode match {
case SchedulingMode.FAIR =>
new FairSchedulingAlgorithm()
case SchedulingMode.FIFO =>
new FIFOSchedulingAlgorithm()
case _ =>
val msg = "Unsupported scheduling mode: $schedulingMode. Use FAIR or FIFO instead."
throw new IllegalArgumentException(msg)
}
}
下面来看看两种调度算法的实现。两种调度算法位于org.apache.spark.scheduler.SchedulingAlgorithm
类,该类中仅定义了一个方法,对两个Schedulable进行比较
def comparator(s1: Schedulable, s2: Schedulable): Boolean
FIFO先入先出调度算法的实现
- 先获取两个Schedulable s1,s2的优先级
- 对两个优先级Schedulable 进行比较
- 如果优先级相同,则对两个Schedulable stageId进行比较
- 如果结果小于0,则优先调度s1,否则优先调度s2
FAIR公平调度算法的实现
- 获取两个Schedulable s