Spark的TaskSetManager(任务管理器)的排序算法

        Spark作业执行中,有一个步骤是给任务进行资源分配,实际上这些任务由一些任务管理器TaskSetManager负责管理,资源分配过程中,会先根据某种排序算法排好序,然后根据就近原则给任务进行资源分配。那么关于TaskSetManager的排序是根据哪个算法呢?现在就来介绍。

        排序算法由两种调度策略FIFOSchedulingAlorithmFairSchedulingAlgorithm的comparator方法提供。

        在FIFO调度策略中,由于根调度池rootPool直接包含了多个作业的任务管理器,在比较时,首先需要比较作业优先级(根据作业编号判断,作业编号越小,优先级越高),如果同一个作业,那就比较调度阶段(调度阶段编号越小,优先级越高)。FIFOSchedulingAlgorithm.comparator的部分源码:

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)
    }
 
    if(res<0){
        true
    }else{
        false
    }
}

        在FAIR调度策略中,包含了两层调度,第一层中,rootPool包含了调度池Pool,第二层中,Pool包含了多个TaskSetManager。其算法步骤,先获取两个调度的饥饿程度(饥饿程度:正在运行的任务是否小于最小任务,如果是,则表明该调度处于饥饿状态。其中最小任务可以通过fairscheduler.xml的minshare参数配置),有了饥饿程度,就可以比较优先级:

  1. 如果一个调度处于饥饿状态,另一个非饥饿状态,先满足处于饥饿状态的调度;
  2. 如果两个调度都处于饥饿状态,则比较资源比,先满足资源比小的调度;
  3. 如果两个调度都处于非饥饿状态,则比较权重比,先满足权重比小的调度;
  4. 如果它们的各种指标相同,则按照调度名字排序。

FairSchedulingAlgorithm.comparator的部分源码:

override def comparator(s1:Schedulable, s2:Schedulable):Boolean{
    //获取配置的最小任务
    val minShare1 = s1.minShare
    val minShare2 = s2.minShare
 
    //正在运行的任务
    val runningTasks1 = s1.runningTasks
    val runningTasks2 = s2.runningTasks
 
    //计算饥饿状态
    val s1Needy = runningTasks1<minShare1
    val s2Needy = runningTasks2<minShare2
 
    //资源比,正在运行的任务数/最小任务数
    val minShareRatio1 = runningTasks1.toDouble/math.max(minShare1,1.0).toDouble
    val minShareRatio2 = runningTasks2.toDouble/math.max(minShare2,1.0).toDouble
 
    //权重比,正在运行的任务数/任务权重
    val taskToWeightRatio1 = runningTasks1.toDouble/s1.weight.toDouble
    val taskToWeightRatio2 = runningTasks2.toDouble/s2.weight.toDouble
 
    if(s1Needy && !s2Needy){
        //s1处于饥饿状态,s2非饥饿状态
        return true
    }else if(!s1Needy && s2Needy){
        //s1处于非饥饿状态,s2处于饥饿状态
        return false
    }else if(s1Needy && s2Needy){
        //s1,s2都处于饥饿状态,比较它们的资源比
        compare = minShareRatio1.compareTo(minShareRatio2)
    }else{
        //s1,s2都处于非饥饿状态,比较它们的权重比
        compare = taskToWeightRatio1.compareTo(taskToWeightRatio2)
    }
 
    if(compare < 0){
        true
    }else if(compare > 0){
        false
    }else{
        //如果它们的各种指标相同,则按照调度名字排序
        s1.name < s2.name
    }
}

 

posted @ 2019-09-05 15:19  KamShing  阅读(619)  评论(0编辑  收藏  举报