YARN是Hadoop 2.0的一个通用的资源管理系统,可为上层应用提供统一的资源管理和调度。

在整个资源管理框架中ResourceManager为Master,NodeManager为Slave
ResourceManager负责对各个NodeManager上的资源进行统一管理和调度。当用户提交一个应用程序时,需要提供一个用以跟踪和管理这个程序的ApplicationMaster,它负责向ResourceManager申请资源,并要求NodeManger启动可以占用一定资源的任务。由于不同的ApplicationMaster被分布到不同的节点上,因此它们之间不会相互影响。

YARN的基本设计思想是将Hadoop 1.0中的JobTracker拆分成了两个独立的服务:一个全局的资源管理器ResourceManager和每个应用程序特有的ApplicationMaster。其中ResourceManager负责整个系统的资源管理和分配,而ApplicationMaster负责单个应用程序的管理(相当于map-reduce job或者DAG jobs)

用户提交作业到ResourceManager,Scheluer可以根据申请的需要,在特定的机器上申请特定的资源(ApplicationMaster负责申请资源时的数据本地化的考虑,ResourceManager将尽量满足其申请需求,在指定的机器上分配Container,从而减少数据移动)

然后在某个NodeManager上分配一个Container来运行ApplicationMaster,ApplicationMaster再根据自身程序需要向ResourceManager申请资源。YARN有一套Container的生命周期管理机制,而ApplicationMaster和其Container之间的管理是应用程序自己定义的任务调度。

1、ResourceManager

ResourceManager负责全局的资源管理和任务调度,将整个集群当计算资源池,只关注分配,不负责应用与容错
主要由调度器scheduler和应用程序管理器ApplicationsManager(AsM)两个组件构成。它支持可插拔的资源调度器,自带了FIFO、Fair Scheduler和Capacity Scheduler三种调度器

ResourceManager是YARN分层结构的本质,承担了JobTracker的角色,这个实体控制整个集群并管理应用程序向基础计算资源的分配。将各个资源部分(计算、内存、带宽等)精心安排给基础NodeManager(YARN 的每节点代理),与ApplicationMaster一起分配资源,与NodeManager一起启动和监视它们的基础应用程序

ResourceManager支持分层级的应用队列,这些队列享有集群一定比例的资源。从某种意义上讲它就是一个纯粹的调度器,它在执行过程中不对应用进行监控和状态跟踪。同样,它也不能重启因应用失败或者硬件错误而运行失败的任务。
ResourceManager是基于应用程序对资源的需求进行调度的; 每一个应用程序需要不同类型的资源因此就需要不同的容器。资源包括:内存,CPU,磁盘,网络等等。

可以看出,这同Mapreduce固定类型的资源使用模型有显著区别,它给集群的使用带来负面的影响。资源管理器提供一个调度策略的插件,负责将集群资源分配给多个队列和应用程序。调度插件可以基于现有的能力调度和公平调度模型。

总的来说,ResourceManager有以下作用

负责集群上所有资源的统一管理和分配
处理来自客户端的请求
监控NodeManager并接收来自的汇报
启动/监控ApplicationMaster并派送资源

ResourceManager作为资源的协调者有两个主要的组件:Scheduler和ApplicationsManager(AsM)

Scheduler负责分配最少但满足application运行所需的资源量给Application。它只是基于资源的使用情况进行调度,并不负责监视/跟踪application的状态,当然也不会处理失败的task。

ApplicationsManager负责处理client提交的job以及协商第一个container以供applicationMaster运行,并且在applicationMaster失败的时候会重新启动applicationMaster。

Scheduler是一个资源调度器,它主要负责协调集群中各个应用的资源分配,保障整个集群的运行效率。Scheduler的角色是一个纯调度器,它只负责调度Containers,不会关心应用程序监控及其运行状态等信息。同样,它也不能重启因应用失败或者硬件错误而运行失败的任务

RM使用resource container概念来管理集群的资源,resource container是资源的抽象,每个container包括一定的内存、IO、网络等资源,不过目前的实现只包括内存一种资源。

Scheduler是一个可插拔的插件,它可以调度集群中的各种队列、应用等。在Hadoop的MapReduce框架中主要有两种Scheduler:Capacity Scheduler和Fair Scheduler,关于这两个调度器后面会详细介绍。

ApplicationManager主要负责接收job的提交请求,为应用分配第一个Container来运行ApplicationMaster,还有就是负责监控ApplicationMaster,在遇到失败时重启ApplicationMaster运行的Container。

ResourceManager功能实现

  1. 资源调度
    Scheduler从所有运行着的application收到资源请求后构建一个全局的资源分配计划,然后根据application特殊的限制以及全局的一些限制条件分配资源。
  2. 资源监视
    Scheduler会周期性的接收来自NM的资源使用率的监控信息,另外applicationMaster可以从Scheduler得到属于它的已完成的container的状态信息。
  3. application提交
    client向AsM获得一个applicationID,然后将application定义以及需要的jar包文件等上传到hdfs的指定目录,并构造资源请求的对象以及application提交的作业发送给AsM。
    AsM接收application的提交并根据application的信息向Scheduler协商申请一个Container,供applicationMaster运行,然后启动applicationMaster,然后向该container所属的NM发送launchContainer信息启动该container,即启动applicationMaster。AsM向client提供运行着的AM的状态信息。
  4. ApplicationMaster的生命周期
    AsM负责系统中所有AM的生命周期的管理
    AsM负责AM的启动,当AM启动后,AM会周期性的向AsM发送heartbeat,默认是1s
    并据此了解AM的存活情况,并且在AM失败时负责重启AM,若是一定时间过后(默认10分钟)没有收到AM的heartbeat,AsM就认为该AM失败了

1.1、Scheduler

Scheduler是ResourceManager专门进行资源管理的一个组件,负责分配NodeManager上的Container资源,NodeManager也会不断发送自己Container使用情况给ResourceManager。

Scheduler资源调度器:根据容量、队列等限制条件(如每个队列分配一定的资源,最多执行一定数量的作业等),将系统中的资源分配给各个正在运行的应用程序。【分配最少但满足应用运行所需的资源量】

调度器仅根据各个应用程序的资源需求进行资源分配,而资源分配单位用一个抽象概念“资源容器”(简称Container)表示,Container是一个动态资源分配单位,它将内存、CPU、磁盘、网络等资源封装在一起,从而限定每个任务使用的资源量。此外,该调度器是一个可插拔的组件,用户可根据自己的需要设计新的调度器,YARN提供了多种直接可用的调度器,比如Fair Scheduler和Capacity Scheduler等。

Scheduler从所有运行着的application收到资源请求后构建一个全局的资源分配计划,然后根据application特殊的限制以及全局的一些限制条件分配资源。

需要注意的是
该调度器是一个“纯调度器”,只是基于资源的使用情况进行调度,并【不负责】任何与具体application相关的工作,这些均交由应用程序相关的ApplicationMaster完成:如不负责监控或者跟踪application的执行状态,也不负责重新启动因application执行失败或者硬件故障而产生的失败任务task

1.2、ApplicationsManager(ASM)

ApplicationsManager(ASM)应用程序管理器:负责管理整个系统中所有的应用程序
包括应用程序提交、与调度器协商资源以启动ApplicationMaster、监控其运行状态并在失败时重新启动等。

1.3、ApplicationMaster(AM)

ApplicationMaster是对运行在Yarn中某个应用的抽象,它其实就是某个类型应用的实例,ApplicationMaster是应用级别的,它的主要功能就是向ResourceManager申请计算资源(Containers)并且和NodeManager交互来执行和监控具体的task。

当用户提交一个应用程序时,需要提供一个用以跟踪和管理这个程序的ApplicationMaster,它负责向ResourceManager申请资源,并要求NodeManger启动可以占用一定资源的任务。由于不同的ApplicationMaster被分布到不同的节点上,因此它们之间不会相互影响。

ApplicationMaster管理在YARN内运行的每个应用程序。用户提交的每个应用程序均包含1个AM。它向RM申请资源,并使用这些资源启动内部的任务,同时负责任务的运行监控和容错等。ApplicationMaster只有获得一个Container后才能启动任务,另外,其本身也是运行在一个Container之中。

计算应用的资源需求,资源可以是静态或动态计算的,静态的一般是Client申请时就指定了,动态则需要ApplicationMaster根据应用的运行状态来决定

每一个应用的ApplicationMaster的职责有

与ResourceManager调度器协商以获取资源(用Container表示)
将得到的任务进一步分配给内部的任务(资源的二次分配)
与NodeManager通信以启动/停止任务,监视容器中任务运行状态和资源使用(CPU、内存等的资源分配)
在任务运行失败时重新为任务申请资源以重启任务等

YARN自带了两个ApplicationMaster实现

1.用于演示AM编写方法的实例程序distributedshell,可申请一定数目的Container以并行运行一个Shell命令或者Shell脚本
2.运行MapReduce应用程序的AM—MRAppMaster

注:RM只负责监控AM,在AM运行失败时候启动它,RM并不负责AM内部任务的容错,这由AM来完成。

ApplicationMaster具体功能描述

ApplicationMaster可以是用任何语言编写的程序,它和ResourceManager和NodeManager之间是通过ProtocolBuf交互,以前是一个全局的JobTracker负责的,现在每个作业都一个,可伸缩性更强,至少不会因为作业太多造成JobTracker瓶颈。同时将作业的逻辑放到一个独立的ApplicationMaster中,使得灵活性更加高,每个作业都可以有自己的处理方式,不用绑定到MapReduce的处理模式上

如何计算资源需求
一般的MapReduce是根据block数量来定Map和Reduce的计算数量,然后一般的Map或Reduce就占用一个Container

如何发现数据的本地化
数据本地化是通过HDFS的block分片信息获取的

在Yarn Application运行期间,ApplicationMaster相当于这个Application的监护人和管理者,负责监控、管理这个Application的所有Attempt在cluster中各个节点上的具体运行,同时负责向Yarn ResourceManager申请资源、返还资源等。可以说,ApplicationMaster与ResourceManager之间的通信是整个Yarn应用从提交到运行的最核心部分,是Yarn对整个集群进行动态资源管理的根本步骤,Yarn的动态性,就是来源于多个Application的ApplicationMaster动态地和ResourceManager进行沟通,不断地申请、释放、再申请、再释放资源的过程。因此,我们一起通过具体实现,来看ApplicationMaster从第一次向Yarn注册自己一直到申请和释放资源时服务端处理的全过程。

MRAppMaster是MapReduce的ApplicationMaster实现,它使得MapReduce计算框架可以运行于YARN之上。在YARN中,MRAppMaster负责管理MapReduce作业的生命周期,包括创建MapReduce作业,向ResourceManager申请资源,与NodeManage通信要求其启动Container,监控作业的运行状态,当任务失败时重新启动任务等

2、NodeManager

NodeManager负责单个节点的资源管理和监控,它定期将资源使用情况汇报给ResourceManager,并接收来自ApplicationMaster的命令以启动Container(YARN中对资源的抽象),回收Container等

NodeManager是每一台机器框架的代理,是节点上的资源和任务管理器。当一个节点启动时,它会向ResourceManager进行注册并发心跳消息(告知RM自己有多少资源可用),等待ResourceManager的指令。

在运行期,通过NodeManager和ResourceManager协同工作,这些信息会不断被更新并保障整个集群发挥出最佳状态。定时地向RM汇报本节点上的资源使用情况和各个Container的运行状态;另一方面,它接收并处理来自AM的Container启动/停止等各种请求。

MRv1 通过插槽管理 Map 和 Reduce 任务的执行,而 NodeManager 管理抽象容器Container,这些容器代表着可供一个特定应用程序使用的针对每个节点的资源。

下面是NodeManager的具体任务列表:
    1.跟踪节点健康状况和资源使用情况 (CPU,内存,硬盘,网络) ,与RM交换信息以确保整个集群平稳运行。
    2.接收ResourceManager的资源分配请求,分配具体的Container给应用
    3.负责各个Container的终生管理,接收并处理来自ApplicationMaster的Container启动/停止等各种请求
    4.管理每个节点上的日志
    5.执行Yarn上面应用的一些额外的服务,比如MapReduce的shuffle过程

2.1、Container管理

NodeManager只负责管理自身的Container,它并不知道运行在它上面应用的信息。负责管理应用信息的组件是ApplicationMaster。

启动或停止Container,监控Container的运行,维护Container的生命周期,监控Container的资源使用情况
管理任务运行时的依赖包(根据ApplicationMaster的需要,启动Container之前将需要的程序及其依赖包、配置文件等拷贝到本地)

NodeManager主要负责启动ResourceManager分配给AM的container以及代表AM的container,并且会监视container的运行情况。在启动container的时候,NM会设置一些必要的环境变量以及将container运行所需的jar包、文件等从hdfs下载到本地,也就是所谓的资源本地化;当所有准备工作做好后,才会启动代表该container的脚本将程序启动起来。启动起来后,NM会周期性的监视该container运行占用的资源情况,若是超过了该container所声明的资源量,则会kill掉该container所代表的进程。

另外,NM还提供了一个简单的服务以管理它所在机器的本地目录。Applications可以继续访问本地目录即使那台机器上已经没有了属于它的container在运行。例如,Map-Reduce应用程序使用这个服务存储map output并且shuffle它们给相应的reduce task。
在NM上还可以扩展自己的服务,yarn提供了一个yarn.nodemanager.aux-services的配置项,通过该配置,用户可以自定义一些服务,例如Map-Reduce的shuffle功能就是采用这种方式实现的。

2.2、Container

Container是Yarn对计算资源的抽象,它其实就是一组CPU和内存资源,所有的应用都会运行在Container中

Container是YARN中的资源抽象(一组分配的系统资源),它封装了节点上的多维度资源(内存、CPU核心、磁盘、网络等)【目前只包含内存和CPU】。以前资源是每个节点分成一个个的Map slot和Reduce slot,现在是一个个Container。以前的资源分配是静态的,目前是动态的,资源利用率更高

YARN中所有的应用都是在container上运行的(启用一个或多个Container),每个Container可以根据需要运行ApplicationMaster(由RM申请)、Map、Reduce或者任意的程序。由ResouceManager中的资源调度器进行异步分配,并由NodeManager进行监控和管理,确保应用程序使用的资源不会超过分配给他的资源。

既然一个Container指的是具体节点上的计算资源,这就意味着Container中必定含有计算资源的位置信息:计算资源位于哪个机架的哪台机器上。所以我们在请求某个Container时,其实是向某台机器发起的请求,请求的是这台机器上的CPU和内存资源。
在Yarn框架中,ResourceManager只负责告诉ApplicationMaster哪些Containers可以用,ApplicationMaster还需要去找资源所在的NodeManager请求分配具体的Container。

资源容器container:

基本的资源单位(CPU、内存等)
Container可以加载任意程序,而且不限于Java
Node可以包含多个Container,也可以是一个大的Container
ApplicationMaster可以根据需要,动态申请和释放Container

Container运行时需提供内部执行的任务命令(可以是任何命令,比如java、Python、C++进程启动命令均可)以及该命令执行所需的环境变量和外部资源(比如词典文件、可执行文件、jar包等)。

在启动一个container的时候,NM就执行该container的default_container_executor.sh,该脚本内部会执行launch_container.sh。launch_container.sh会先设置一些环境变量,最后启动执行程序的命令。对于MapReduce而言,启动AM就执行org.apache.hadoop.mapreduce.v2.app.MRAppMaster;启动map/reduce task就执行org.apache.hadoop.mapred.YarnChild。

一个应用程序所需的Container分为两大类:

  1. 运行ApplicationMaster的Container:
    由ResourceManager(向内部的资源调度器)申请和启动,用户提交应用程序时可指定唯一的ApplicationMaster所需的资源
  2. 运行各类任务的Container:
    由ApplicationMaster向ResourceManager申请,由ApplicationMaster与NodeManager通信以启动之

以上两类Container可能在任意节点上,它们的位置通常而言是随机的,即ApplicationMaster可能与它管理的任务运行在一个节点上。【一个节点会运行多个Container,但一个Container不会跨节点】