本篇文章将深入介绍 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 SchedulerHadoop doc - Capacity SchedulerHadoop: 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 资源给两个队列时便视作公平。
  • 每个队列内部仍可以有不同的调度策略。队列的默认调度策略可以通过顶级元素 进行配置,如果没有配置,默认采用公平调度。

三)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。

文中对三个调度器的功能、特征、配置、实现进行了较为详细的分析。各位同学若对其中实现细节有兴趣可深入源码,进一步探究。


参考文章:

YARN Capacity Scheduler (容量调度器) 不完全指南 | Bambrow's Blog - 对 CS 中配置属性有较详细讲解

Capacity Scheduler - vs - Fair Scheduler

Yarn 调度器Scheduler详解 - 对 Fair 队列配置有较详细讲解

YARN调度器(Scheduler)详解

详解Yarn中三种资源调度器(FIFO Scheduler、Capacity Scheduler、Fair Scheduler)和配置自定义队列实现任务提交不同队列

Yarn Fair Scheduler详解 - 源码分析

Yarn源码分析6-Reserve机制 | 亚坤的博客 (yoelee.github.io)

YARN资源调度原理剖析

Hadoop 三大调度器源码分析及编写自己的调度器

【深入浅出 Yarn 架构与实现】5-2 Yarn 三种调度器的更多相关文章

  1. 第1节 yarn:14、yarn集群当中的三种调度器

    yarn当中的调度器介绍: 第一种调度器:FIFO Scheduler  (队列调度器) 把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源 ...

  2. YARN的三种调度器的使用

    YRAN提供了三种调度策略 一.FIFO-先进先出调度器 YRAN默认情况下使用的是该调度器,即所有的应用程序都是按照提交的顺序来执行的,这些应用程序都放在一个队列中,只有在前面的一个任务执行完成之后 ...

  3. 【深入浅出 Yarn 架构与实现】3-1 Yarn Application 流程与编写方法

    本篇学习 Yarn Application 编写方法,将带你更清楚的了解一个任务是如何提交到 Yarn ,在运行中的交互和任务停止的过程.通过了解整个任务的运行流程,帮你更好的理解 Yarn 运作方式 ...

  4. 【深入浅出 Yarn 架构与实现】2-1 Yarn 基础库概述

    了解 Yarn 基础库是后面阅读 Yarn 源码的基础,本节对 Yarn 基础库做总体的介绍.并对其中使用的第三方库 Protocol Buffers 和 Avro 是什么.怎么用做简要的介绍. 一. ...

  5. 【深入浅出 Yarn 架构与实现】2-3 Yarn 基础库 - 服务库与事件库

    一个庞大的分布式系统,各个组件间是如何协调工作的?组件是如何解耦的?线程运行如何更高效,减少阻塞带来的低效问题?本节将对 Yarn 的服务库和事件库进行介绍,看看 Yarn 是如何解决这些问题的. 一 ...

  6. 【深入浅出 Yarn 架构与实现】2-4 Yarn 基础库 - 状态机库

    当一个服务拥有太多处理逻辑时,会导致代码结构异常的混乱,很难分辨一段逻辑是在哪个阶段发挥作用的. 这时就可以引入状态机模型,帮助代码结构变得清晰. 一.状态机库概述 一)简介 状态机由一组状态组成: ...

  7. 【深入浅出 Yarn 架构与实现】2-2 Yarn 基础库 - 底层通信库 RPC

    RPC(Remote Procedure Call) 是 Hadoop 服务通信的关键库,支撑上层分布式环境下复杂的进程间(Inter-Process Communication, IPC)通信逻辑, ...

  8. 【深入浅出 Yarn 架构与实现】3-2 Yarn Client 编写

    上篇文章介绍了编写 Yarn Application 的整体框架流程,本篇文章将详细介绍其中 Client 部分的编写方式. 一.Yarn Client 编写方法 本篇代码已上传 Github: Gi ...

  9. 【深入浅出 Yarn 架构与实现】3-3 Yarn Application Master 编写

    本篇文章继续介绍 Yarn Application 中 ApplicationMaster 部分的编写方法. 一.Application Master 编写方法 上一节讲了 Client 提交任务给 ...

  10. SSH深度历险(一)深入浅出Hibernate架构(一)-------映射解析——七种映射关系

            ORM,全称是(Object Relational Mapping),即对象关系映射.ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对数据 ...

随机推荐

  1. bgp多线互联

    BGP(边界网关协议)主要用于互联网AS(自治系统)之间的互联,BGP的最主要功能在于控制路由的传播和选择最好的路由. 中国网通 .中国电信.中国铁通.教育网和一些大的民营IDC运营商都具有AS号,全 ...

  2. linux缓冲区溢出尝试

    #include <stdio.h>#include <string.h>char Lbuffer[] = "01234567890123456789======== ...

  3. Python-pytest -> 在自动化测试中,如何切换不同的测试环境

    在构建自动化测试的脚本时候,我们可能会有不同环境的测试需求,如何实现在不同的测试环境之间切换呢?接下来介绍的这种方法,可以自定义命令行参数,从而根据不同的参数值实现不同环境的切换. 解决办法: 使用h ...

  4. Day14-封装、继承、多态

    封装.继承.多态 一.封装 package Demo; //类 private私有 public class student { //属性私有 //名字 private String name; // ...

  5. 中国人民公安大学 Chinese people’ public security university 网络对抗技术 实验报告4

    中国人民公安大学 Chinese people' public security university 网络对抗技术 实验报告   实验四 恶意代码技术     学生姓名 陈禹 年级 2018 区队 ...

  6. ssh免密码登录服务器

    A机为本地主机(即用于控制其他主机的机器) B机为远程主机(即被控制的机器server)B机:192.168.3.145 假如A机无密码登录B机器     A机上的命令: 1,ssh-keygen - ...

  7. MySQL innodb存储引擎的数据存储结构

    InnoDB存储引擎的数据存储结构 B+ 树 为什么选择B+树? 因为B+树的叶子节点存储了所有的data,所以它的非叶子节点可以存储更多的key,使得树更矮:树的高度几乎就是I/O的次数,所以选择更 ...

  8. SpringBoot测试类注入Bean失败原因

    首先针对SpringBoot的测试类,2.2版本之前和2.2版本之后是不一样的,在2.2版本之前需要贴注解@SpringBootTest和@RunWith(SpringRunner.class)需要在 ...

  9. 实验1 Python开发环境使用和编程初体验

    # print输出的几种用法 # 用法1:用于输出单个字符串或单个变量 print('hey, u') # 用法2: 用于输出多个数据项,用逗号分隔 print('hey', ' u') x,y,z ...

  10. 接口返回JSON字符串压缩和解压

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.IO;usi ...