YARN 1 | 青训营笔记

127 阅读18分钟

这是我参与「第四届青训营 」笔记创作活动的第8天

YARN 概述

初识调度系统

简易分配模型

一种简易的分配模型参考如下:

  • 保障公平性
  • 保障高效性
  • 保障高可用
  • “尽可能多”?
  • 个性化需求

调度系统演进

概述

如今,我们已经由信息科技时代(IT)进化到数据科技时代(DT),数据中蕴藏的海量信息激发我们开发各种计算模型和计算框架进行挖掘,而这些计算模型和计算框架最终都需要落地计算。同时数据计算方式也发生了很大变革,从单机到分布式集群再到大规模数据中心,计算越来越快。对于大型互联网公司而言,为了完成各种对外服务以及对内挖掘等任务,需要的硬件资源数以万计,具有较高的成本。

当用有限资源解决有限资源无法满足的需求时就需要调度。如何充分挖掘硬件资源潜力、灵活进行资源管理与调度以及提高集群整体利用率成为降本增效的关键问题。资源资源管理与调度主要解决资源请求和可用资源的映射(Mapping) 问题,也就是将负载的资源请求与当前计算集群中的可用物理资源通过一定的调度策略进行匹配(Matching)。

集群资源管理与调度系统的核心目标是: 设计出更好的资源管理与调度策略,使得整个集群在保障任务SLA的前提下能够实现更高的资源利用率、更快的计算任务完成速度。

  • 严格的多租户间公平、容量保障
  • 调度过程的高吞吐与低延迟
  • 高可靠性与高可用性保障
  • 高可扩展的调度策略
  • 高集群整体物理利用率
  • 满足上层任务的个性化调度需求
  • 任务持续、高效、稳定运行

调度系统设计的基本问题

  • 资源异质性与工作负载异质性
  • 数据局部性
  • 抢占式与非抢占式调度
  • 资源分配粒度

大数据场景下的计算任务往往呈现层级结构,例如:作业级(Job)-任务级(Task)-实例级(Instance),从计算任务视角来看,此时资源调度系统就面临资源分配粒度问题,资源分配粒度主要存在三种方式:(1)群体分配策略(Gang Scheduler),即要么全满足要么全不满足,Flink和MPI任务依赖这种方式;(2)增量满足式分配策略,只要分配部分资源就可以启动运行,MR采用这种方式;(3)资源储备策略,资源达到一定量才能启动作业,在未获得足够资源时作业可以先持有目前已经分配的资源并等待其他作业释放资源,调度系统不断获取新资源并进行储备和积累,直到分配到的资源量达到最低标准后开始运行,在作业启动前已经分配的资源处于闲置状态。

  • 饿死与死锁问题

饿死是由于调度策略不当而导致计算任务长时间无法获得开始执行所需要的最少资源量,例如支持优先级调度时,如果不断出现高优先级任务,那么低优先级任务可能饿死;死锁是由于资源分配不当而导致整个调度系统无法正常执行,例如在资源储备策略下,如果AB两个作业启动作业需要的最小资源为2/3,那么如果两个任务被分配了1/2的资源时,就导致死锁。调度系统出现死锁必然表现为某些作业处于饿死状态,但计算任务饿死的情景并不一定意味着调度系统处于死锁状态。

  • 资源隔离方法

为了减少任务之间的干扰需要进行一定的隔离措施,LXC是一种轻量级的内核虚拟化技术,LXC在资源管理方面依赖于 Linux 内核的 cgroups 子系统,cgroups 子系统是 Linux 内核提供的一个基于进程组的资源管理框架,可以为特定的进程组限定可以使用的资源。其他技术有Intel RDT。

资源管理与调度系统范型

  • 集中式调度系统

    • 基本原理:中心式调度系统融合了资源管理和任务调度,有一个中心式的 JobTracker 负责进行集群资源的合理分配、任务的统一调度、集群计算节点信息的统计维护、任务执行过程中的状态管理等。

    • 优点:

      • JobTracker 能够感知集群中所有资源和任务的执行状态,能够进行全局最优的资源分配和调度,避免任务间的干扰,适当进行任务抢占,保证任务计算效率和服务质量;
      • 架构模型简单,只有一个全局的管理者负责进行所有管理。
    • 缺点:

      • JobTracker 作为集群的中心,存在单点瓶颈问题,不能支持大规模集群;
      • 内部实现异常复杂,一个调度器中需要实现所有的功能模块,可扩展性差;
      • 负载变更会导致系统需要进行不断的迭代,这将增加系统的复杂性,不利于后期的维护和扩展;
      • 只支持单类型的任务,MR 类型的批处理任务;
    • 典型的调度系统:Hadoop1.*版本;K8S中的kube-scheduler,Quasar。

  • 两层调度系统

    • 产生背景:为了解决集中式调度系统的扩展性问题,系统实现复杂,可扩展性差,不能支持不同类型任务等缺点。

    • 实现原理:将资源管理和任务调度解耦。集群资源管理器负责维护集群中的资源信息并将资源分配给具体的任务,任务管理器负责申请资源并将申请到的资源根据用户逻辑进行细分和具体的任务调度。

    • 优点:

      • 资源管理器只负责资源分配,任务调度由应用完成,提高了系统的扩展性;
      • 任务调度逻辑由具体的任务完成,能够提供对不同类型任务的支持;
      • 内部实现模块化,利于维护和扩展;
    • 缺点:

      • 任务无法感知全局的资源情况,只能基于request/offer来进行资源获取,无法有效避免异构负载之间的性能干扰问题;
      • 任务调度和资源管理解耦不利于实现多任务间的优先级抢占;
      • 所有任务的资源请求都需要资源管理器进行处理,此外其还需要与节点管理器之间维持通信,导致资源管理器存在单点问题;
    • 典型系统:Mesos,YARN,Fuxi

    •   Mesos 最先将资源管理和任务调度解耦的 offer-based(基于资源供应)方案,其有一个中心的资源管理器,通过分配策略(DRF)将资源分配给不同的计算框架,每个计算框架依据自身的逻辑、资源偏好等采取增量或者 All-or-Nothing 的方式决定接受还是拒绝分配的资源,计算框架根据分配到的资源进行下一步的资源分配和任务执行。

  • 共享状态调度系统

    • 产生背景:前面的调度器存在一个问题就是计算框架在进行资源申请的时候无法获知到集群的全局资源信息,这就导致无法进行全局最优的调度,共享状态调度器就提供了这个问题的一种解决方式。

    • 基本原理:是一个半分布式的架构,通过共享集群状态为应用提供全局的资源视图,并采用乐观并发机制进行资源申请和释放,来提高系统的并发度。

    • 优点:

      • 支持全局最优调度;
      • 能够一定程度的提高并发度;
    • 缺点:

      • 高并发资源请求下会造成频繁的资源竞争;
      • 不利于资源分配的公平性;
      • 资源全局副本维护模块存在单点瓶颈;
    • 典型系统:Omega

  • 分布式调度系统

    • 产生背景:提高系统吞吐率和并发度

    • 基本原理:分布式调度器之间没有通讯协作,每个分布式调度器根据自己最少的先验知识进行最快的决策,每个调度器单独响应任务,总体的执行计划与资源分配服从统计意义。

    • 优点:提高吞吐量和并发度

    • 缺点:

      • 调度质量得不到保障;
      • 资源非公平分配;
      • 不能支持多租户管理;
      • 不能避免不同任务之间的性能干扰;
    • 典型系统:Sparrow 是一个完全的去中心化的分布式调度系统,通常用于满足低延迟高吞吐的短任务场景。系统包含多个调度器,这些调度器分布在集群的节点上,作业可以提交给任何一个分布式调度器。其核心是采用随机调度模型,利用二次幂采样原理针对每个任务随机采样出两个服务节点,选择任务等待队列最短的一个作为调度结果,也可以采用异步预定的方式进行资源调度。实验证明近似最优解能够有效的满足大规模毫秒调度性能的需求。

  • 混合式调度系统

    • 产生背景:针对一些特定的混合任务调度场景,某些任务需要比较快的调度响应,而其他任务不需要很快的调度响应,但是需要保证调度质量。

    • 基本原理:设计两条资源请求和任务调度路径,保留两层调度的优点,同时兼顾分布式调度器的优势。对于没有资源偏好且响应要求高的任务采用分布式调度器,对于资源调度质量要求较高的采用集中式资源管理器进行资源分配。

    • 优点:

      • 能够针对不同类型的任务进行不同方式的调度;
      • 为应用层提供灵活的接口和性能保障;
    • 缺点:复杂化了计算框架层的业务逻辑;调度系统内部也需要针对两种不同的调度器进行协同处理;

    • 典型调度系统:Mercury:微软的混合调度机制,中心式调度器对调度质量要求较高的作业进行公平的资源分配,分布式调度器对时间敏感和吞吐率要求高的作业进行调度。

YARN 设计思想

演化背景

Hadoop 1.0 时代:由分布式存储系统 HDFS 和分布式计算框架 MapReduce(MR v1) 组成,MR v1 存在很多局限:

  • 可扩展性差:JobTracker 兼备资源管理和任务控制,是系统最大的瓶颈;
  • 可靠性差:采用 master/slave 结构,master 存在单点故障问题;
  • 资源利用率低:基于槽位的资源分配模型,各槽位间资源使用差异大;
  • 无法支持多种计算框架:只支持 MR 任务,无法支持其他计算框架;

  1. Hadoop 2.0 时代:解决了 Hadoop 1.0 时代中 HDFS 和 MR 中存在的问题:
  • YARN(MR v2) 在 MR v1 的基础上发展而来,将资源管理和任务控制解耦,分别由 Resource Manager 和 ApplicationMaster 负责,是一个两层调度系统;
  • Hadoop YARN(Yet Another Resource Negotiator) 支持多种计算框架的统一资源管理平台;

离线调度生态介绍

  • 用户逻辑层:数据分析任务、模型训练任务等
  • 作业托管层:管理各种类型上层任务
  • 分布式计算引擎层:各种针对不同使用场景的计算引擎,例如:MR、Spark、Flink 等
  • 集群资源管理层:YARN
  • 裸金属层:众多物理节点组成

YARN 面临的挑战

  1. 公平性:各租户能够公平的拿到资源运行任务
  2. 高性能:高调度吞吐、低调度延迟,保障资源快速流转
  3. 高可用:集群要具备很强的容错能力
  4. 单集群规模提升:原生 YARN 单集群仅支持 5K
  5. 高集群资源利用率
  6. 高任务运行质量保障

YARN 整体架构

系统架构

上图为 YARN 架构,主要包含两大角色:

  • Resource Manager

    • 整个集群的大脑,负责为应用调度资源,管理应用生命周期;
    • 对用户提供接口,包括命令行接口,API, WebUI 接口;
    • 可以同时存在多个RM、,同一时间只有一个在工作,RM 之间通过 ZK 选主;
  • Node Manager

    • 为整个集群提供资源, 接受 Container 运行;
    • 管理Contianer的运行时生命周期, 包括Localization, 资源隔离, 日志聚合等;

YARN上运行的作业在运行时会访问外部的数据服务,常见的如 HDFS, Kafka 等;在运行结束后由 YARN 负责将日志上传到 HDFS;

任务运行核心流程

核心模块

Resource Manager

整体架构

主要职责

总的来说,RM 负责集群所有资源的统一管理和分配,接收各节点汇报信息并按照一定策略分配给各个任务;

  • 与客户端交互,处理来自客户端的请求
  • 启动和管理 AM,运行失败时自动重试
  • 管理所有 NM,接收 NM 的汇报信息并下达管理指令
  • 资源管理与调度

    • 将资源按照一定方式组织起来,例如:资源池
    • 将任务按照一定方式组织起来,例如:队列
    • 接收来自各个 AM 的资源请求
    • 按照一定分配策略将资源分配给 AM

状态机管理

RMApp 状态机

  • NEW_SAVING: 收到提交的应用程序后,创建 RMAppImpl 对象并将基本信息持久化;
  • ACCEPTED:调度器接受该应用程序后所处的状态,任务等待被分配资源;
  • RUNNING:任务成功获取到资源并在节点运行

RMAppAttempt 状态机

  • SCHEDULED: 通过 Scheduler 合法性检查后所处的状态,开始为该 App 分配资源;
  • ALLOCATED_SAVING:收到分配的 Container 后,在持久化完成前所处的状态;
  • ALLOCATED:信息持久化完成后所处的状态;
  • LAUNCHED:RM 的 ApplicationMasterLauncher 与 NM 通信以启动 AM 时所处的状态;

RMContainer 状态机

  • RESERVED: 开启资源预留时,当前节点不能满足资源请求时所处的状态;
  • ALLOCATED:调度器分配一个 Container 给 AM;
  • ACQUIRED:AM 获取到分配的 Container 后所处的状态;
  • EXPIRED: AM 获取到 Container 后,若在一定时间内未启动 Container,RM 会强制回收该 Container;

RMNode 状态机

  • DECOMMSIONED: 节点下线后的状态;
  • UNHEALTHY:节点处于不健康状态,健康检测脚本异常或磁盘故障;
  • LOST:超过一定时间(默认 10 分钟)未与 RM 发生心跳后所处的状态;

调度分析

调度流程: YARN 调度流程由心跳触发

  • AM 定期与 RM 保持心跳,并将资源请求记录在 RM 中;
  • 触发时机: 由节点心跳触发针对此节点的调度;
  • 找 Label: 根据节点 Label 找到对应 Lable 下的所有队列;
  • 找队列: 将队列进行 DRF 排序, 找到当前最“饥饿”的队列;
  • 找应用: 将此队列内所有应用按照优先级进行排序(优先级由用户提交时指定), 找到优先级最高的应用, 优先级相同时按DRF 算法排序;
  • 找资源请求: 将此应用内的所有资源请求按照优先级排序(优先级由计算引擎指定), 找到优先级最高的资源请求进行资源分配;

  1. 典型调度器对比

Node Manager

整体架构

主要职责

总的来说,NM 是节点代理,从 AM 接受命令(启停 Container)并执行,通过心跳方式向 RM 汇报节点状态并领取命令(清理 Container)。

  • 与 RM 交互

    • 心跳汇报节点健康状况和 Container 运行状态;
    • 领取 RM 下达的命令;
  • 与 AM 交互

    • 启动容器
    • 停止容器
    • 获取容器状态

状态机管理

Application

  • INITING: Application 初始化状态,创建工作目录和日志目录;
  • FINISHING_CONTAINERS_WAIT:调等待回收 Container 所占用的资源所处的状态;
  • APPLICATION_RESOURCE_CLEANINGUP:Application 所有 Container 占用的资源被回收后所处的状态;

Container

  • LOCALIZING: 正在从 HDFS 下载依赖的资源;
  • EXITED_WITH_SUCCESS:Container 运行脚本正常退出执行;
  • CONTAINER_CLEANUP_AFTER_KILL:Container 被 kill 后所处的状态;

LocalizedResource

  • DOWNLOADING: 资源处于下载状态;
  • LOCALIZED:资源下载完成;
  • FAILED:资源下载失败;

节点健康检查机制

节点健康检测机制是 NM 自带的健康状况诊断机制。通过该机制 NM 可时刻掌握自己健康状况并及时汇报给 RM,RM 根据 NM 健康情况决定是否为其分配新任务。

  • 自定义 Shell

    • NodeHealthScriptRunner 服务周期性执行节点健康状况检测脚本;
    • 若输出以 “ERROR”开头,节点处于 unhealthy 状态并随心跳上报给 RM,RM 拉黑节点并停止分配新任务;
    • 脚本一直执行,一旦节点变为 healthy 状态,RM 会继续为该节点分配新任务;
  • 检测磁盘损坏数目

    • LocalDirsHandlerService 服务周期性检测 NM 本地磁盘好坏,一旦发现正常磁盘比例低于一定阈值则节点处于 unhealthy 状态;
    • NM 判断磁盘好坏的标准:如果一个目录具有读、写和执行权限,则目录正常;

重要机制

公平性保障

Fair Share 调度策略

队列配置 minShare 和 maxShare,当队列空闲时按照一定策略将资源分配给其他活跃队列;

优点: 保障公平的前提下实现队列间资源共享,提高资源利用率,缓解繁忙队列压力;

image.png

两种类型 Fair Share
  • Steady Fair Share: TotalResource * S.weight

  • Instantaneous Fair Share:

    • 定义

      • 所有队列 Fair Share 之和 <= TotalResource;
      • S.minShare <= Fair Share <= S.maxShare;
    • 目标

      • 找到一个 R 使其满足:
      • R * (All S.wieght)<= TotalResource;
      • S.minShare <= R * S.weight <= S.maxShare;
    • 结果

      • 若 S.minShare > R * S.weight, Fair Share = S.minShare
      • 若 S.maxShare < R * S.weight,Fair Share = S.maxShare
      • 其他 Fair Share = R * S.weight
Fair Share 计算逻辑
  • 计算 Total Resource
  • 初始化 R 上限 RMax

    • 获取所有 non-fixed Schedulable 的 maxShare
    • 初始化 R 为 1,每次翻倍
    • 直到所有 Schedulable 分完所有资源
  • 通过二分法寻找 R [0,RMax]

    • mid = (left + right) / 2.0
    • 若 plannedResourceUsed == totalResource,right = mid;
    • 若 plannedResourceUsed < totalResource,left = mid;
    • 若 plannedResourceUsed > totalResource,right = mid;
  • 计算 Fair Share

    • 若 S.minShare > right * S.weight, Fair Share = S.minShare;
    • 若 S.maxShare < right * S.weight, Fair Share = S.maxShare;
    • 其他情况 Fair Share = right * S.weight

DRF 调度策略

在保证公平性的前提下进行资源降维,以达到更好的分配效果;

什么是 DRF 调度策略?

  • DRF 是最大最小公平算法在多维资源上的具体实现;
  • 旨在使不同用户的“主分享量”最大化的保持公平;

最大最小公平算法:最大化最小资源需求的满足度

  • 资源按照需求递增的顺序进行分配;
  • 用户获取的资源不超过自身需求;
  • 对未满足的用户,等价分享剩余资源;

例如下面场景:A B C D 四个用户的资源需求分别是 2、2.6、4、5份,现在总共有 10 份资源,首先将所有资源均分,每个用户得到 2.5 份资源。对于 A 用户多分配 0.5 份,继续将这 0.5 份资源平均分配给 B C D,B 用户得到 2.666 份资源。会继续将 B 多分配的 0.066 份资源平均分配给 C 和 D。

DRF 调度策略示例
  • 场景:系统有 <9CPU, 18G>,A 每个任务需要 <1CPU,4G>,B 每个任务需要 <3CPU,1G>,对于 A 因为:1/9 < 4/18,所以 A 任务的主资源是内存,B 任务的主资源是 CPU;
  • 数学模型:一定约束条件下的最优化问题,下面 x 代表 A 任务的个数,y 代表 B 任务的个数

    • 最大化资源分配 max(x,y)

    • 约束条件:

      • (x+3y)<=9(CPU约束);
      • (4x+y)<= 18(内存约束);
      • 4x/18 == 3y/9(主资源公平约束);
  • 最终计算得到: x=3,y=2

高性能保障

状态机管理

  • 状态机由一组状态(初始状态、中间状态和最终状态)组成,状态机从初始状态开始运行,接收一组特定事件,经过一系列中间状态后,到达最终状态并退出;
  • 每种状态转换由一个四元组表示:转换前状态、转换后状态、事件和回调函数;
  • YARN 定义了三种状态转换方式如下所示:

事件处理模型

YARN 采用了基于事件驱动的并发模型,具有很强的并发性可提高系统性能。

  • RM 中所有处理请求都会作为事件进入系统;
  • AsyncDispatcher 负责传递事件给相应事件调度器--EventHandler;
  • 事件调度器可能将该事件转发给另外一个事件调度器或带有有限状态机的事件处理器;
  • 处理结果也以事件形式输出,新事件会再次被中央异步调度器转发给下一个事件调度器,直至处理完成。

高可用保障

RM 高可用

热备方案:集群中存在一个对外服务的 Active Master 和若干 Standby Master,一旦 Active Master 故障,立即采取一定策略选取某个 Standby Master 转换为 Active Master 正常对外提供服务;

基于共享存储的 HA 解决方案:Active Master 不断将信息写入共享存储系统(ZK),故障切换时 Standby Master 从共享存储恢复数据,待信息完全同步后切换至 Active Master;

两种切换模式

  • 手动模式:使用 “yarn rmadmin”命令将现在的 Active Master 切换为 Standby 并选择一个 Standby 切换为 Active Master;
  • 自动模式:使用 ZK 的 ActiveStandbyElector 进行选主操作,ZK 中有一个 /yarn-leader-election/yarn1 的锁节点,所有 RM 在启动时去竞争写一个 Lock 子节点:/yarn-leader-election/yarn1/ActiveBreadCrumb,该节点是临时节点。ZK 保证最终只有一个 RM 能够创建成功,创建成功的为 Active Master;

Client 、 AM、NM 自动重试:切主时各组件基于配置文件中的所有 RM 采用 round-robin 轮询方式不断尝试连接 RM 直到命中 Active Master;

NM 高可用

  • 相关信息存储至 leveldb 数据库;
  • NM 重启时加载 yarn-nm-recovery 下的 leveldb 数据库;