• storm源码阅读笔记之任务调度算法


    3种Scheduler概述

    • EventScheduler:将系统中的可用资源均匀地分配给需要资源的topology,其实也不是绝对均匀,后续会详细说明
    • DefaultScheduler:和EvenetScheduler差不多,只不过会先将其它topology不需要的资源重新收集起来,再进行EventScheduler
    • IsolationScheduler:用户可定义这个topology的机器资源,storm分配的时候会优先分配这些topology,以保证分配给该topology的机器只为这一个topology服务

    DefaultScheduler

    • 调用cluster的needsSchedualerTopologies方法获得需要进行任务分配的topologies
    • 开始分别对每一个topology进行处理
      • 调用cluster的getAvailableSlots方法获得当前集群可用的资源,以<node,port>集合的形式返回,赋值给available-slots
      • 获得当前topology的executor信息并转化为<start-t ask-id,end-task-id>集合存入all-executors,根据topology计算executors信息,采用compute-executors算法,稍后会讲解
      • 然后调用EventScheduler的get-alive-assigned-node+port->executors方法获得该topology已经获得的资源,返回<node+port,executor>集合的形式存入alive-assigned,为什么要计算当前topology的已分配资源情况而不是计算集群中所有已分配资源?,猜测可能是进行任务rebalance的时候会有用吧。
      • 接着就调用slot-can-reassign对alive-assigned中的slots信息进行判断,选出其中能被重新分配的slot存入变量can-reassigned
      • 这样可用的资源就由available-slotscan-reassigned两部分组成
      • 接下来计算当前topology能使用的全部slot数目total-slots--to-use:min(topology的NumWorker数,available-slots+can-reassigned)
      • 如果total-slots--to-use>当前已分配的slots数目,则调用bad-slots方法计算可被释放的slot
      • 调用cluster的freeSlots方法释放计算出来的bad-slot
      • 最后调用EventScheduler的schedule-topologies-evenly进行分配
      • 继续下一个topology

    主要流程梳理:获得当前集群空闲资源->计算当前topology的executor信息(分配时会用得上)->计算可重新分配和可释放的资源->分配

    EventScheduler

    EventScheduler调度算法与Default相比少了一个计算可重新分配资源的环节,直接利用Supervisor中空闲的slot进行分配,在此不再细讲。

    EventScheduler和DefaultScheduler调度举例:

    这两种调度机制在一般情况下调度结果基本保持一致,所以一起来看:

    集群初始状态

    接下来我们提交3个topology

    Topology

    Worker

    Executer

    Task

    T-1

    3

    8

    16

    T-2

    5

    10

    10

    T-3

    3

    5

    10

    1、提交T-1

    • sort-slots算法对可用slots进行处理,结果为{[s1 6700] [s2 6700] [s3 6700] [s4 6700] [s1 6701] [s2 6701] [s3 6701] [s4 6701] [s1 6702] [s2 6702] [s3 6702] [s4 6702] [s1 6703] [s2 6703] [s3 6703] [s4 6703]}
    • compute-executors算法计算后得到的Executor列表为:{[1 2] [3 4] [5 6] [7 8] [9 10] [11 12] [13 14] [15 16]};注:格式为[start-task-id end-task-id],共8个worker,第一个包含2个task,start-task-id为1,end-task-id为2,所以记为[1 2],后面依次类推...compute-executors算法会在下一篇博客中详解
    • 8个Executor在3个worker上的分布状态为[3,3,2]
    • 分配结果为:
      • {[1 2] [3 4] [5 6]} -> [s1 6700]
      • {[7 8] [9 10] [11 12]} -> [s2 6700]
      • {[13 14] [15 16]} -> [s3 6700]

    分配后集群状态为:

    2、提交T-2

    • 可用的slot经过sort-slots后:{[s1 6701] [s2 6701] [s3 6701] [s4 6700] [s1 6702] [s2 6702] [s3 6702] [s4 6701] [s1 6703] [s2 6703] [s3 6703] [s4 6702] [s4 6703]}
    • comput-executors计算后得到的executor列表:{[1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9] [10 10]}
    • 10个executor在5个worker上的分布为[2,2,2,2,2]
    • 分配结果为:
      • {[1 1] [2 2]} -> [s1 6701]
      • {[3 3] [4 4]} -> [s2 6701]
      • {[5 5] [6 6]} -> [s3 6701]
      • {[7 7] [8 8]} -> [s4 6700]
      • {[9 9] [10 10]} -> [s1 6702]

    分配后集群状态为:

    3、提交T-3

    • sort-slots后slot列表为:{[s1 6703] [s2 6702] [s3 6702] [s4 6701] [s2 6703] [s3 6703] [s4 6702] [s2 6704] [s3 6704] [s4 6703] [s4 6704]}
    • compute-executors后得到的executor列表为:{[1 2] [3 4] [5 6] [7 8] [9 10]}
    • 5个executor在3个worker上的分布为:[2,2,1]
    • 分配结果为:
      • {[1 2] [3 4]} -> [s1 6703]
      • {[5 6] [7 8]} -> [s2 6702]
      • [9 10] -> [s3 6702]

    分配后集群状态为:

    如图,此任务调度方式也不是绝对均匀的,s1已经满负荷运转,而s4才刚使用一个slots。

    此篇用到的算法如comput-executors、sort-slots、slots-can-reassign、bad-slots、sort-slots等会在下篇博客中专门探讨

    吴承桀的博客
  • 相关阅读:
    Windows 7 32位上硬盘安装linux[ubuntu13.04] 双系统
    【笨嘴拙舌WINDOWS】BMP图片浏览器
    【笨嘴拙舌WINDOWS】设备无关图(*.bmp)
    【笨嘴拙舌WINDOWS】GDI对象之位图
    Android-Java-对象在内存中的简单关系图
    Android-Java-类与对象的关系
    Android-Java-面向对象与面向过程举例
    Android-Java-面向对象与面向过程的简单理解
    Android-ANR异常
    Android-Genymotion Unable to load VirtualBox engine
  • 原文地址:https://www.cnblogs.com/Chuck-wu/p/4948529.html
Copyright © 2020-2023  润新知