YARN

Yarn 概述、调度器与调度算法

YARN

概述

image-20220703193516001
  • Yet Another Resource Negotiator,资源(内存、cpu等)管理器,相当于一个分布式操作系统平台,MapReduce等运算程序相当于运行于OS上的应用程序

  • Hadoop1.0中,jobTracker的任务过多(接收任务、资源调度、监控TaskTracker运行情况),虽然实现简单但容易产生单点故障问题

  • ResourceManager:整个集群的资源管理(单节点的cpu*节点数、单节点的内存*节点数)

    • 处理客户端请求,监控NodeManager,启动ApplicationMaster
    • 一个集群有且只有一个RM,包含两个主要组件:定时调用器(Scheduler)、应用管理器(ApplicationManager)
    • 调度器:一种策略或算法,Client提交一个任务后,根据所需资源和集群当前资源状况进行分配——只负责向应用程序分配资源,不监控或跟踪应用程序的状态
    • 应用管理器(AM):管理单个任务的运行,监控、跟踪状态
  • NodeManager:每个节点上运行的资源和任务管理器

    • NodeManager是ResourceManager在每台机器的上代理
    • 管理容器,监控容器的资源使用情况(cpu,内存,磁盘,网络等),向ResourceManager/Scheduler发送资源的使用报告,接收并处理来自AM的Container启动/停止等各种请求
  • ApplicationMaster:

    • Client提交一个Application,就新建一个ApplicationMaster
    • ApplicationMaster向ResourceManager申请容器资源,获得资源后将Application发送到容器上启动、分布式计算
  • 数据太多难以移动,因此将容易移动的应用程序发布到各个节点进行计算

  • Container:任务运行的环境,Container封装了任务运行所需的资源——可以跨节点;由NodeManager启动和管理,并被它监控;被ResourceManager调度

  • 全局组件: RM(Scheduler,ApplicationManager)、NM

  • Job独有组件:ApplicationMaster、Container

  • 提交一个程序的流程:

    • Client向Yarn提交Application(假设是一个MapReduce任务)
    • RM的ApplicationManager向NodeManager通信,为Application分配一个运行Application对应ApplicationMaster的容器
    • ApplicationMaster向RM注册并启动后,计算应用完成所需要的资源,拆分Application为多个task(task需要运行在一个或多个容器中),向RM申请需要的资源(容器),定时向RM发送心跳
    • 申请容器后,ApplicationMaster与容器对应的VM通信,将作业分发到对应的NM的容器运行——对于一个MapReduce任务,容器中运行的可能是Map任务,可能是Reduce任务
    • 容器中运行的任务向ApplicationMaster发送心跳。程序运行完成,ApplicationMaster向RM注销并释放容器的资源
  • 运行一个mapreduce程序的流程:(假设有3个服务器)

    • 作业提交

      • Client调用方法job.waitForCompletion,将一个MapReduce job提交给集群
      • Client向RM申请一个job id
      • RM返回job的资源提交路径和job id给Client
      • Client提交jar包、切片信息、配置文件到指定的提交路径
      • Client提交完资源,向RM申请运行MrAppMaster(MapReduce对ApplicationMaster的实现)
    • 作业初始化

      • RM收到Client的请求,将job添加到容量调度器
      • 某个空闲的NM领取该Job
      • NM创建Container,产生MRAppmaster,下载Client提交的资源到NM本地
    • 任务分配

      • MrAppMaster向RM申请运行多个MapTask的资源
      • RM将MapTask分配给另外两个NM,另两个 NM领取任务并创建容器
    • 任务运行

      • MR向两个接收到任务的NM发送程序启动脚本,它们分别启动MapTask
      • MrAppMaster等待所有MapTask运行完毕,向RM申请容器,运行ReduceTask
      • 程序运行完毕,MR向RM申请注销
    • 进度和状态更新:YARN中的任务将其进度和状态返回应用管理器,Client每秒(mapreduce.client.progressmonitor.pollinterval参数设置)向应用管理器请求进度更新, 展示给用户

    • 作业完成

      • Client每5秒调用waitForCompletion()(mapreduce.client.completion.pollinterval参数)检查作业是否完成
      • 作业完成后,应用管理器和Container清理工作状态,作业信息被作业历史服务器存储,以备核查
  • 关键参数

    • RM相关
      • yarn.resourcemanager.scheduler.class:调度器,默认为容量调度器
      • yarn.resourcemanager.scheduler.client.thread-count:RM处理调度器请求的线程数,默认50
    • NM相关
      • yarn.nodemanager.resource.detect-hardware-capabilities:yarn自己检测硬件进行配置,默认为false
      • yarn.nodemanager.resource.count-logical-processors-as-cores:虚拟核数当作cpu核数,默认false
      • yarn.nodemanager.resource.pcores-vcores-multiplier:虚拟核数和物理核数乘数。4核8线程则为2,默认1.0
      • yarn.nodemanager.resource.pcores-vcores-multiplier:NM使用内存,默认8G
      • yarn.nodemanager.resource.system-reserved-memory-mb:NM为系统保留多少内存
      • yarn.nodemanager.resource.cpu-vcores:NM使用CPU核数,默认8个
      • yarn.nodemanager.pmem-check-enabled:是否开启物理内存检查限制container,默认打开
      • yarn.nodemanager.vmem-check-enabled:是否开启虚拟内存检查限制container,默认打开
      • yarn.nodemanager.vmem-pmem-ratio:虚拟内存物理内存比例
    • Container相关
      • yarn.scheduler.minimum-allocation-mb:容器最小内存,默认1G
      • yarn.scheduler.maximum-allocation-mb:容器最大内存,默认8G
      • yarn.scheduler.minimum-allocation-vcores:容器最小CPU核数,默认1个
      • yarn.scheduler.maximum-allocation-vcores:容器最大CPU核数,默认4个

Yarn调度器和调度算法

  • 主要有三种:
    • FIFO
    • 容量(Capacity Scheduler)
    • 公平(Fair Scheduler)
  • Hadoop默认资源调度器为Capacity Scheduler
  • CDH默认调度器为Fair Scheduler

FIFO调度器

  • 单队列,YARN集群中所有的资源全部调集过来,分配给当前任务,根据提交作业的先后顺序服务(不支持多队列,生产环境很少使用)

image-20220705165757853

容量调度器

image-20220705165847385

  • 每个队列可以配置一定资源,队列采用FIFO调度

  • 管理员为每个队列设置资源使用下限和上限

  • 一个队列中的资源有剩余,则可暂时共享给其他队列,如果该队列有新的提交任务,则回收资源

  • 支持多用户、多作业同时进行

  • 限定同一用户提交的作业所占资源,以防止一个用户独占队列所有资源(上图ss、cls为用户)

  • 资源分配算法:

    image-20220705171516841
    • 假设队列A有20%资源,队列B有50%资源,队列C有30%资源,队列C下有两个子队列ss、和cls,分别占据15%资源
    • 队列资源分配:深度优先算法,优先选择资源占用率最低的队列(此时优先选择队列A)
    • 作业资源分配:默认按照作业的优先级和提交时间顺序分配资源(此时如果作业1的优先级高,则先分配作业1的资源)
    • 容器分配:
      • 按容器优先级分配资源(这里有三个容器,根据优先级分配任务)
      • 如果优先级相同,按数据本地性原则
        • 任务和数据在同一节点
        • 任务和数据在同一机架
        • 任务和数据不在同一节点、同一机架
  • 相关参数的配置:

    (1)capacity:队列的资源容量(百分比),所有队列的容量之和应小于100

    (2)maximum-capacity:队列的资源使用上限(百分比)

    (3)user-limit-factor:每个用户最多可使用的资源量(百分比)。假设值为30,则每个用户使用的资源量不能超过该队列容量的30%

    (4)maximum-applications :集群或者队列中同时处于等待和运行状态的应用程序数目上限——超过该上限,后续提交的任务将被拒绝,默认值为 10000。所有队列的数目上限可通过参数yarn.scheduler.capacity.maximum-applications设置,单个队列可通过参数yarn.scheduler.capacity.<queue-path>.maximum-applications设置

    (5)maximum-am-resource-percent:集群中用于运行应用程序ApplicationMaster的资源比例上限

    (6)state :状态可以为STOPPED或者 RUNNING,如果一个队列处于STOPPED状态,用户不能将任务提交到该队列或者它的子队列。如果ROOT队列处于STOPPED状态,用户不能向集群中提交任务

    (7)acl_submit_applications:限定哪些Linux用户/用户组可向给定队列提交应用程序——如果一个用户可以向某个队列提交应用程序,则它可以向所有子队列提交应用程序。用户之间或用户组之间用“,”分割,用户和用户组之间用空格分割,如user1, user2 group1, group2

    (8)acl_administer_queue:为队列指定一个管理员,管理员可控制该队列的所有应用程序,如杀死任意一个应用程序等

公平调度器

image-20220705182501440

  • 异同:

    • 相同点:
      • 支持多队列
      • 可设置队列的资源上下限
      • 队列资源剩余,可共享给其他队列
      • 限定同一用户提交作业所占资源
    • 不同点:
      • 核心调度策略:
        • 容量:资源利用率低的队列优先
        • 公平:资源的缺额比例大的队列优先
      • 每个队列单独设置资源分配方式
        • 容量:FIFO、DRF
        • 公平:FIFIO、FAIR、DRF
  • 缺额:时间尺度上,所有作业获得公平的资源。某一时刻一个作业应获资源和实际获取资源的差距为缺额

    image-20220705191739804
  • 资源分配方式:

    • FIFO:若每个队列资源分配策略为FIFO,则公平调度器==容量调度器
    • Fair:整个时间线上,所有Job平均获取资源。默认情况下,调度器只是对内存资源做公平的调度和分配——集群中只有一个任务在运行时,此任务占用整个集群的资源,当其他的任务提交,第一个任务缓慢释放资源,分配给新的Job,每个job最终能获取几乎一样多的资源
    • DRF(Dominant Resource Fairness):
      • 以上资源是单一标准,例如只考虑内存(Yarn默认)
      • 假设集群有100CPU和10T内存,应用A需要(2 CPU,300GB),应用B需要(6CP,100GB), 则两个应用分别需要A(2%CPU, 3%内存)和B(6%CPU, 1%内存)——A是内存主导,B是CPU主导,此时DRF策略对不同应用进行不同资源(CPU和内存)做不同比例的限制
  • 相关参数配置

    (1)yarn.scheduler.fair.allocation.file: “allocation”文件的位置。“allocation”文件用来描述queue以及它们的属性的配置文件。这个文件必须为格式严格的xml文件。如果为相对路径,那么将会在classpath下查找此文件(conf目录下)。默认值为“fair-scheduler.xml”

    (2)yarn.scheduler.fair.user-as-default-queue:是否将与allocation有关的username作为默认的queue name,当queue name没有指定的时候。默认值为true

    (3)yarn.scheduler.fair.preemption:是否使用“preemption”(优先权,抢占),默认为fasle

    (4)yarn.scheduler.fair.assignmultiple:是否在允许在一个心跳中,发送多个container分配信息。默认值为false。

    (5)yarn.scheduler.fair.max.assign:如果assignmultuple为true,在一次心跳中,最多发送分配container的个数。默认为-1,无限制

    (6)yarn.scheduler.fair.sizebaseweight:是否将application的大小(Job的个数)作为权重。默认为false,如果为true,复杂的application将获取更多的资源

常用命令

  • 查看任务
    • 列出所有Application:yarn application -list
    • 根据Application状态过滤:yarn application -list -appStates 状态(状态包括ALL、NEW、 NEW_SAVING、SUBMITTED、ACCEPTED、RUNNING、FINISHED、FAILED、KILLED)
    • Kill任务:yarn application -kill application_1612577921195_0001(最后的参数为Application-Id)
  • 查看日志:
    • 查询Application日志:yarn logs -applicationId <ApplicationId>
    • 查询Container日志:yarn logs -applicationId <ApplicationId> -containerId <ContainerId>
  • 查看尝试运行的任务:
    • 所有尝试运行的任务:yarn applicationattempt -list <ApplicationId>
    • 查看某个任务状态:yarn applicationattempt -status <ApplicationAttemptId>
  • 查看容器:
    • 所有容器:yarn container -list <ApplicationAttemptId>
    • 查看容器状态:yarn container -status <ContainerId>
  • 查看节点状态:yarn node -list -all
  • 查看队列信息:yarn queue -status <QueueName>