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


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

            排序算法由两种调度策略FIFOSchedulingAlorithm和FairSchedulingAlgorithm的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
        }
    }

     

  • 相关阅读:
    Linux下Apache服务器并发优化
    centos 7 mount win共享文件夹 开机自动挂载
    自学 phpredis 的心路历程
    VM虚拟机下centos7 无法上网的问题解决办法
    php headers_sent 函数的作用
    is_file 与 file_exists 的区别
    php 面向对象 中的self
    php 去除所有空格 包括中文空格圆角空格
    滑动窗口滚动条触发事件
    PHP中file_exists与is_file、is_dir的区别,以及执行效率的比较 转自#冰雪傲骨#
  • 原文地址:https://www.cnblogs.com/SysoCjs/p/11357009.html
Copyright © 2020-2023  润新知