Spark源码阅读02-Spark核心原理之调度算法

Spark应用程序提交执行时,会根据RDD依赖关系形成有向无环图(DAG),然后交给DAGScheduler进行划分作业和调度阶段,这些作业之间没有依赖关系,对于多个作业之间的调度,Spark提供两种调度策略:一种是FIFO策略,(目前默认的模式);一种是FAIR模式,该模式的调度可以通过两个参数的配置来决定Job执行的优先模式,两个参数分别是minShare(最小任务数)和weight(任务的权重)。该调度策略的执行过程和代码如下:

1.创建调度池

在TaskSchedulerImpl.initilaize方法中先创建根调度池rootPool对象,然后根据系统配置调度模式创建调度创建器,针对两种调度策略具体实例化FIFOSchedulableBuilder或FairSchedulableBuilder,最终使用调度创建器buildPools方法在根调度池rootPool下创建调度池。代码实现如下:

def initialize(backend: SchedulerBackend) {

this.backend = backend

schedulableBuilder = {

//根据调度模式配置调度池

schedulingMode match {

//使用FIFO调度方式

case SchedulingMode.FIFO =>

new FIFOSchedulableBuilder(rootPool)

//使用FAIR调度方式

case SchedulingMode.FAIR =>

new FairSchedulableBuilder(rootPool, conf)

case _ =>

throw new IllegalArgumentException(s"Unsupported $SCHEDULER_MODE_PROPERTY: " +

s"$schedulingMode")

}

}

schedulableBuilder.buildPools()

}

2.调度池加入调度内容

在TaskSchedulerImpl.submitTasks方法中,先把调度阶段拆分为任务集,然后把这些任务集交给管理器TaskManager进行管理,最后把该任务集的管理器加入到调度池中,等待分配执行。

override def submitTasks(taskSet: TaskSet) {

val tasks = taskSet.tasks

logInfo(“Adding task set " + taskSet.id + " with " + tasks.length + " tasks”)

this.synchronized {

//创建任务集的管理,用于管理这个任务集的声明周期

val manager = createTaskSetManager(taskSet, maxTaskFailures)

val stage = taskSet.stageId

val stageTaskSets =

taskSetsByStageIdAndAttempt.getOrElseUpdate(stage, new HashMap[Int, TaskSetManager])

stageTaskSets.foreach { case (_, ts) =>

ts.isZombie = true

}

stageTaskSets(taskSet.stageAttemptId) = manager

//将该任务集的管理器加入到系统调度池中,由系统统一调配,该调度器属于应用级别

//支持FIFO和FAIR(公平调度)两种

schedulableBuilder.addTaskSetManager(manager, manager.taskSet.properties)

}

}

3.提供已排序的任务集管理器

在TaskSchedulerImpl.resourceOffers方法中进行资源分配时,会从根调度池rootPools获取已经排序的任务管理器,该排序算法由两种调度策略FIFOSchedulingAlgorithm和FairSchedulingAlgorithm的comparator方法提供。代码实现如下:

def resourceOffers(offers: IndexedSeq[WorkerOffer]): Seq[Seq[TaskDescription]] = synchronized {

//获取按照资源调度策略排序好的TaskSetManager

val sortedTaskSets = rootPool.getSortedTaskSetQueue

}

(1)FIFO调度策略实现代码如下:

private[spark] class FIFOSchedulingAlgorithm extends SchedulingAlgorithm {

override def comparator(s1: Schedulable, s2: Schedulable): Boolean = {

//获取作业优先级,实际上是作业编号

val priority1 = s1.priority

val priority2 = s2.priority

var res = math.signum(priority1 - priority2)

//如果是同一个作业,再比较调度阶段优先级

if (res == 0) {

val stageId1 = s1.stageId

val stageId2 = s2.stageId

res = math.signum(stageId1 - stageId2)

}

res < 0

}

}

(2)FIAR调度策略实现代码如下:

private[spark] class FairSchedulingAlgorithm extends SchedulingAlgorithm {

//比较两个调度优先级方法,返回true表示前者优先级高,false表示后者优先级高

override def comparator(s1: Schedulable, s2: Schedulable): Boolean = {

//最小任务数

val minShare1 = s1.minShare

val minShare2 = s2.minShare

//正在运行的任务数

val runningTasks1 = s1.runningTasks

val runningTasks2 &#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值