乐趣区

关于hadoop:深入浅出-Yarn-架构与实现52-Yarn-三种调度器

本篇文章将深刻介绍 Yarn 三种调度器。Yarn 自身作为资源管理和调度服务,其中的资源调度模块更是重中之重。上面将介绍 Yarn 中实现的调度器性能,以及外部执行逻辑。

一、简介

Yarn 最次要的性能就是资源管理与调配。本篇文章将对资源分配中最外围的组件调度器(Scheduler)进行介绍。
调度器最现实的指标是有资源申请时,立刻满足。然而因为物理资源是无限的,就会存在资源如何调配的问题。针对不同资源需求量、不同优先级、不同资源类型等,很难找到一个完满的策略能够解决所有的利用场景。因而,Yarn 提供了多种调度器和可配置的策略供咱们抉择。
Yarn 资源调度器均实现 ResourceScheduler 接口,是一个插拔式组件,用户能够通过配置参数来应用不同的调度器,也能够本人依照接口标准编写新的资源调度器。在 Yarn 中默认实现了三种调速器:FIFO Scheduler、Capacity Scheduler、Fair Scheduler。
官网对三种调度器的介绍图。看个大略意思就行,随着调度器的不断更新迭代,这个图不再合乎当下的状况。

二、FIFO

最简略的一个策略,仅做测试用。
用一个队列来存储提交期待的工作,先提交的工作就先分资源,有残余的资源就给后续排队期待的工作,没有资源了后续工作就等着之前的工作开释资源。
长处:
简略,开箱即用,不须要额定的配置。早些版本的 Yarn 用 FIFO 作为默认调度策略,后续改为 CapacityScheduler 作为默认调度策略。
毛病:
除了简略外都是毛病,无奈配置你各种想要的调度策略(限度资源量、限度用户、资源争夺等)。

三、CapacityScheduler

一)CS 简介

Capacity Scheduler(后以 CS 简写代替)以队列为单位划分资源。会给每个队列配置最小保障资源和最大可用资源。最小配置资源保障队列肯定能拿到这么多资源,有闲暇可共享给其余队列应用;最大可用资源限度队列最多能应用的资源,避免适度耗费。
队列外部能够再嵌套,造成层级构造。队列内资源默认采纳 FIFO 的形式调配。如下图所示。

长处:

  • 队列最低资源保障,避免小利用饿死;
  • 闲暇容量共享,当队列配置资源有闲暇时可共享给其余队列应用

毛病:

  • 队列配置繁琐,父队列、子队列都要独自配置优先级、最大资源、最小资源、用户最大资源、用户最小资源、用户权限配置等等。工程中会写个程序,主动生成该配置;

二)CS 特色

  • 分层队列 (Hierarchical Queues):反对队列分层构造,子队列可调配父队列可用资源。
  • 容量保障 (Capacity Guarantees):每个队列都会配置最小容量保障,当集群资源缓和时,会保障每个队列至多能分到的资源。
  • 弹性 (Elasticity):当队列配置资源有闲暇时,能够调配给其余有资源需要的队列。当再次须要这些资源时能够争夺回这些资源。
  • 安全性 (Security):每个队列都有严格的 ACL,用于管制哪些用户能够向哪些队列提交应用程序。
  • 多租户 (Multi-tenancy):提供全面的限度以避免单个应用程序、用户和队列从整体上独占队列或集群的资源。
  • 优先级调度 (Priority Scheduling):此性能容许以不同的优先级提交和调度应用程序。同时队列间也反对优先级配置(2.9.0 后反对)。
  • 相对资源配置 (Absolute Resource Configuration):管理员能够为队列指定相对资源,而不是提供基于百分比的值(3.1.0 后反对)。
  • 资源池配置:可将 NodeManager 宰割到不同的资源池中,资源池中配置队列,进行资源隔离。同时资源池有共享和独立两种模式。在共享状况下,多余的资源会共享给 default 资源池。

三)CS 配置

假如队列层级如下:

root
├── prod
└── dev
    ├── eng
    └── science

能够通过配置 capacity-scheduler.xml 来实现:

<configuration>
  <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>prod,dev</value>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.dev.queues</name>
    <value>eng,science</value>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.prod.capacity</name>
    <value>40</value>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.dev.capacity</name>
    <value>60</value>
  </property>

  <property>            
    <name>yarn.scheduler.capacity.root.dev.eng.capacity</name>
    <value>50</value>
  </property>

  <property>            
    <name>yarn.scheduler.capacity.root.dev.science.capacity</name>
    <value>50</value>
  </property>
</configuration>

除了容量配置外,还能够配置单个用户或者程序可能应用的最大资源数,同时能够运行几个利用,权限 ACL 管制等,不是本篇重点,不再开展。可参考:cloudera – Capacity Scheduler、Hadoop doc – Capacity Scheduler、Hadoop: Capacity Scheduler yarn 容量调度配置。

四)CS 实现

这里仅关注 CS 资源分配的过程。
CS 调配的是各 NM 节点上的闲暇资源,NM 资源汇报请到之前的文章《4-3 RM 治理 NodeManager》中理解。

1、资源申请形容

AM 通过心跳汇报资源申请,蕴含的信息如下。

message ResourceRequestProto {
  optional PriorityProto priority = 1;  // 优先级
  optional string resource_name = 2;        // 冀望资源所在节点或机架
  optional ResourceProto capability = 3;    // 资源量
  optional int32 num_containers = 4;        // Container 数目
  optional bool relax_locality = 5 [default = true];     // 是否松弛本地性
  optional string node_label_expression = 6;    // 所在资源池
}

2、资源更新入口

NM 发送心跳给 RM 后,RM 会发送 NODE_UPDATE 事件,这个事件会由 CapacityScheduler 进行解决。

    case NODE_UPDATE:
    {NodeUpdateSchedulerEvent nodeUpdatedEvent = (NodeUpdateSchedulerEvent)event;
      RMNode node = nodeUpdatedEvent.getRMNode();
      setLastNodeUpdateTime(Time.now());
      nodeUpdate(node);
      if (!scheduleAsynchronously) {
        // 重点
        allocateContainersToNode(getNode(node.getNodeID()));
      }
    }

重点在 allocateContainersToNode(),外部逻辑如下:

  • 从根队列往下找,找到 most ‘under-served’ 队列(即 已分配资源 / 配置资源 最小的);
  • 先满足曾经预留资源(RESERVED)的容器
  • 再解决未预留的资源申请,如果资源不够,则进行 RESERVE,期待下次调配

这里有个预留的概念(之后会有文章专门介绍 reserve 机制):

  • RESERVED 是为了避免容器饿死;
  • 传统调度:比方一堆 1G 和 2G 的容器申请,以后集群全被 1G 的占满了,当一个 1G 的容器实现后,下一个还是会调度 1G,因为 2G 资源不够;
  • RESERVED 就是为了避免这种状况产生,所以先把这个资源预留进去,谁也别用,等下次有资源了再补上,直到满足这个容器资源申请。

四、FairScheduler

一、Fair 简介

同 Capacity Seheduler 相似,Fair Scheduler 也是一个多用户调度器,它同样增加了多层级别的资源限度条件以更好地让多用户共享一个 Hadoop 集群,比方队列资源限度、用户应用程序数目限度等。
在 Fair 调度器中,咱们不须要事后占用肯定的系统资源,Fair 调度器会为所有运行的 job 动静的调整系统资源。如下图所示,当第一个大 job 提交时,只有这一个 job 在运行,此时它取得了所有集群资源;当第二个小工作提交后,Fair 调度器会调配一半资源给这个小工作,让这两个工作偏心的共享集群资源。

Fair 调度器的设计指标是为所有的利用调配偏心的资源(对偏心的定义能够通过参数来设置)。
长处:

  • 调配给每个应用程序的资源取决于其优先级;
  • 它能够限度特定池或队列中的并发运行工作。

二)Fair 特色

  • 偏心调度器,就是可能共享整个集群的资源
  • 不必事后占用资源,每一个作业都是共享的
  • 每当提交一个作业的时候,就会占用整个资源。如果再提交一个作业,那么第一个作业就会分给第二个作业一部分资源,第一个作业也就开释一部分资源。再提交其余的作业时,也同理。也就是说每一个作业进来,都有机会获取资源。
  • 权重属性,并把这个属性作为偏心调度的根据。如把两个队列权重设为 2 和 3,当调度器调配集群 40:60 资源给两个队列时便视作偏心。
  • 每个队列外部仍能够有不同的调度策略。队列的默认调度策略能够通过顶级元素 <defaultQueueSchedulingPolicy> 进行配置,如果没有配置,默认采纳偏心调度。

三)Fair 配置

在 FairScheduler 中是通过在 fair-scheduler.xml 中配置队列权重,来实现「偏心」的。
计算时是看(以后队列权重 / 总权重)失去以后队列能分得资源的百分比。
更具体参数配置,可参考:Yarn 调度器 Scheduler 详解

<queue name="first">
  <minResources>512mb, 4vcores</minResources>
  <maxResources>30720nb, 30vcores</maxResources>
  <maxRunningApps>100</maxRunningApps>
  <schedulingMode>fair</schedulingMode>
  <weight>2.0</weight>
</queue>

<queue name="second">
  <minResources>512mb, 4vcores</minResources>
  <maxResources>30720nb, 30vcores</maxResources>
  <maxRunningApps>100</maxRunningApps>
  <schedulingMode>fair</schedulingMode>
  <weight>1.0</weight>
</queue>

五、Fair Scheduler 与 Capacity Scheduler 区别

相同点

  • 都反对多用户多队列,即:实用于多用户共享集群的应用环境
  • 都反对层级队列
  • 反对配置动静批改,更好的保障了集群的稳固运行。
  • 均反对资源共享,即某个队列中的资源有残余时,可共享给其余缺资源的队列
  • 单个队列均反对优先级和 FIFO 调度形式

不同点

  • Capacity Scheduler 的调度策略是,能够先抉择资源利用率低的队列,而后在队列中通过 FIFO 或 DRF 进行调度。
  • Fair Scheduler 的调度策略是,能够应用偏心排序算法抉择队列,而后再队列中通过 Fair(默认)、FIFO 或 DRF 的形式进行调度。

六、小结

本篇介绍了 Yarn 中组重要的资源调度模块 ResourceScheduler,作为一个可插拔组件,默认有三种实现形式 Fifo、CapacityScheduler、FairScheduler。
文中对三个调度器的性能、特色、配置、实现进行了较为具体的剖析。各位同学若对其中实现细节有趣味可深刻源码,进一步探索。

退出移动版