Yarn简易剖析

1,020 阅读8分钟

一、YARN架构设计

ResourceManager(RM)

  • 负责对各NM上的资源进行统一管理和调度。将AM分配空闲的Container运行并监控其运行状态。对AM申请的资源请求分配相应的空闲Container。主要由两个组件构成:调度器和应用程序管理器。

调度器(Scheduler)

  • 调度器根据容量、队列等限制条件(如每个队列分配一定的资源,最多执行一定数量的作业等),将系统中的资源分配给各个正在运行的应用程序。调度器仅根据各个应用程序的资源需求进行资源分配,而资源分配单位是Container(容器),从而限定每个任务使用的资源量。Shceduler不负责监控或者跟踪应用程序的状态,也不负责任务因为各种原因而需要的重启(由ApplicationMaster负责)。总之,调度器根据应用程序的资源要求,以及集群机器的资源情况,为应用程序分配封装在Container中的资源。
  • 调度器是可插拔的,例如CapacityScheduler、FairScheduler。

应用程序管理器(Applications Manager)

  • 应用程序管理器负责管理整个系统中所有应用程序,包括应用程序提交、与调度器协商资源以启动AM、监控AM运行状态并在失败时重新启动等,跟踪分给的Container的进度、状态也是其职责。

NodeManager(NM)

  • NM是每个节点上的资源和任务管理器。它会定时地向RM汇报本节点上的资源使用情况和各个Container的运行状态;同时会接收并处理来自AM的Container启动/停止等请求。

ApplicationMaster(AM)

  • 用户提交的应用程序均包含一个AM,负责应用的监控,跟踪应用执行状态,重启失败任务等。ApplicationMaster是应用框架,它负责向ResourceManager协调资源,并且与NodeManager协同工作完成Task的执行和监控。MapReduce就是原生支持的一种框架,可以在YARN上运行MapReduce作业。有很多分布式应用都开发了对应的应用程序框架,用于在YARN上运行任务,例如Spark,Storm等。如果需要,我们也可以自己写一个符合规范的YARN application。

容器(Container)

  • 是YARN中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等,当AM向RM申请资源时,RM为AM返回的资源便是用Container 表示的。YARN会为每个任务分配一个Container且该任务只能使用该Container中描述的资源。

进程:

  • ResourceManager
  • NodeManager

命令:

  • yarn application –list
  • yarn application –kill -applicationId<application ID>
  • yarn logs -applicationId<application ID>

二、YARN资源管理与调度、参数配置

  • 在YARN中,资源管理由ResourceManager和NodeManager共同完成,其中,ResourceManager中的调度器负责资源的分配,而NodeManager则负责资源的供给和隔离。
  • ResourceManager将某个NodeManager上资源分配给任务(这就是所谓的资源调度)后,NodeManager需按照要求为任务提供相应的资源,甚至保证这些资源应具有独占性,为任务运行提供基础的保证,这就是所谓的资源隔离。

Memory资源的调度和隔离

  • 基于以上考虑,YARN允许用户配置每个节点上可用的物理内存资源,注意,这里是“可用的”,因为一个节点上的内存会被若干个服务共享,比如一部分给YARN,一部分给HDFS,一部分给HBase等,YARN配置的只是自己可以使用的,配置参数如下:
    • (1)yarn.nodemanager.resource.memory-mb
      • 表示该节点上YARN可使用的物理内存总量,默认是8192(MB),注意,如果节点内存资源不够8GB,则需要调减小这个值,而YARN不会智能的探测节点的物理内存总量。
    • (2)yarn.nodemanager.vmem-pmem-ratio
      • 任务每使用1MB物理内存,最多可使用虚拟内存量,默认是2.1。
    • (3)yarn.nodemanager.pmem-check-enabled
      • 是否启动一个线程检查每个任务正使用的物理内存量,如果任务超出分配值,则直接将其杀掉,默认是true。
    • (4)yarn.nodemanager.vmem-check-enabled
      • 是否启动一个线程检查每个任务正使用的虚拟内存量,如果任务超出分配值,则直接将其杀掉,默认是true。
    • (5)yarn.scheduler.minimum-allocation-mb
      • 单个任务可申请的最少物理内存量,默认是1024(MB),如果一个任务申请的物理内存量少于该值,则该对应的值改为这个数。
    • (6)yarn.scheduler.maximum-allocation-mb
      • 单个任务可申请的最多物理内存量,默认是8192(MB)。
  • 默认情况下,YARN采用了线程监控的方法判断任务是否超量使用内存,一旦发现超量,则直接将其杀死。由于Cgroups对内存的控制缺乏灵活性(即任务任何时刻不能超过内存上限,如果超过,则直接将其杀死或者报OOM),而Java进程在创建瞬间内存将翻倍,之后骤降到正常值,这种情况下,采用线程监控的方式更加灵活(当发现进程树内存瞬间翻倍超过设定值时,可认为是正常现象,不会将任务杀死),因此YARN未提供Cgroups内存隔离机制。

CPU资源的调度和隔离

  • 目前的CPU被划分成虚拟CPU(CPU virtual Core),这里的虚拟CPU是YARN自己引入的概念,初衷是,考虑到不同节点的CPU性能可能不同,每个CPU具有的计算能力也是不一样的,比如某个物理CPU的计算能力可能是另外一个物理CPU的2倍,这时候,你可以通过为第一个物理CPU多配置几个虚拟CPU弥补这种差异。用户提交作业时,可以指定每个任务需要的虚拟CPU个数。在YARN中,CPU相关配置参数如下:
    • (1)yarn.nodemanager.resource.cpu-vcores
      • 表示该节点上YARN可使用的虚拟CPU个数,默认是8,注意,目前推荐将该值设值为与物理CPU核数数目相同。如果你的节点CPU核数不够8个,则需要调减小这个值,而YARN不会智能的探测节点的物理CPU总数。
    • (2)yarn.scheduler.minimum-allocation-vcores
      • 单个任务可申请的最小虚拟CPU个数,默认是1,如果一个任务申请的CPU个数少于该数,则该对应的值改为这个数。
    • (3)yarn.scheduler.maximum-allocation-vcores
      • 单个任务可申请的最多虚拟CPU个数,默认是32。
      • CDH官方经过大量验证,container容器最大分配vcore最好不要超过5,所以我一般设置为4
  • 默认情况下,YARN是不会对CPU资源进行调度的,需要配置相应的资源调度器。

三、YARN三种调度器

  • 理想情况下,我们应用对Yarn资源的请求应该立刻得到满足,但现实情况资源往往是有限的,特别是在一个很繁忙的集群,一个应用资源的请求经常需要等待一段时间才能的到相应的资源。在Yarn中,负责给应用分配资源的就是Scheduler。其实调度本身就是一个难题,很难找到一个完美的策略可以解决所有的应用场景。为此,Yarn提供了多种调度器和可配置的策略供我们选择。
  • 在Yarn中有三种调度器可以选择:FIFO Scheduler ,Capacity Scheduler,FairScheduler。

FIFO Scheduler(先进先出调度器)

  • FIFO Scheduler把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源,待最头上的应用需求满足后再给下一个分配,以此类推。
  • FIFO Scheduler是最简单也是最容易理解的调度器,也不需要任何配置,但它并不适用于共享集群。大的应用可能会占用所有集群资源,这就导致其它应用被阻塞。在共享集群中,更适合采用Capacity Scheduler或Fair Scheduler,这两个调度器都允许大任务和小任务在提交的同时获得一定的系统资源。
  • 从图中可以看出,在FIFO 调度器中,小任务会被大任务阻塞。

Capacity Scheduler(计算调度器)

  • Capacity调度器有一个专门的队列用来运行小任务,但是为小任务专门设置一个队列会预先占用一定的集群资源,这就导致大任务的执行时间会落后于使用FIFO调度器时的时间。

Fair Scheduler(公平调度器)

  • Fair调度器中,不需要预先占用一定的系统资源,Fair调度器会为所有运行的Task动态的调整系统资源。如下图所示,当Task1提交时,只有这Task1在运行,此时它获得了所有集群资源;当Task2提交后,Fair调度器会分配一定的资源给Task2,让这两个任务公平的共享集群资源。
  • 需要注意的是,在下图Fair调度器中,从Task2提交到获得资源会有一定的延迟,因为它需要等待Task1释放占用的Container。Task2执行完成之后也会释放自己占用的资源,Task1又获得了全部的系统资源。最终的效果就是Fair调度器即得到了高的资源利用率又能保证小任务及时完成。