3.2 YARN
YARN是Hadoop集群的资源管理系统。从2.0版本开始,Hadoop对MapReduce框架做了彻底的设计重构,而被称为YARN。在旧的Hadoop架构中,JobTracker(作业追踪器)负责整个集群的资源管理和作业调度监控。YARN架构打破了这种模型,将这两部分功能分开,让资源管理器(Resource Manager)负责整个集群的资源管理和调度,让应用程序主控器(Application Master)负责一个作业的执行,例如作业调度、作业监控和容错等。这一更改消除了JobTracker的瓶颈,从而使得Hadoop集群可以扩展到更大的配置。
需要注意的是,在YARN中我们把作业(Job)的概念换成了应用程序(Application),这是因为从Hadoop2开始,运行的应用程序不只是MapReduce了,还有可能是其他应用程序。
3.2.1 架构组成
如图3-7所示,YARN主要由以下几个组件组成。
· Resource Manager(资源管理器,简称RM):全局(Global)的进程。
· Node Manager(节点管理器,简称NM):运行在每个节点(Node)上的进程。
· Application Master(应用程序主控器,简称AM):特定应用(Application-specific)的进程。
· Scheduler(调度器):ResourceManager的一个组件,用于给应用调度资源。
· Container(容器):节点上一组CPU和内存资源。
图3-7 YARN架构
Container是YARN对计算机计算资源的抽象,它主要就是一组CPU和内存资源(如图3-3上Containers的状态信息),所有的应用都会运行在Container中。Application Master是对运行在YARN中某个应用的抽象,它其实就是某个类型应用的实例,Application Master是针对特定应用的,它的主要功能就是向Resource Manager(全局的)申请计算资源(即Containers),并且和Node Manager交互来执行和监控具体的任务。Resource Manager和Node Manager两个进程主要负责系统管理方面的任务。Scheduler是Resource Manager专门进行资源调度的一个组件,负责各个集群中应用的资源分配,即负责分配Node Manager上的Container资源,Node Manager也会不断地把自己Container的使用情况发送给Resource Manager。YARN的架构图(见图3-7)展示了Resource Manager、Node Manager、Application Master和Container等几个组件的关系。下面我们详细介绍各个组件。
1.Container(容器)
Container是YARN框架的计算单元,是具体执行应用任务(如map task、reduce task)的基本单位。Container和集群节点的关系是:一个节点会运行多个Container,但一个Container不会跨节点。一个Container就是一组分配的系统资源,主要包含以下两种系统资源(还有磁盘、网络等资源):
· CPU内核
· 内存资源
既然一个Container指的是具体节点上的计算资源,这就意味着Container中必定含有计算资源的位置信息:计算资源位于哪个机架的哪台机器上。所以我们在请求某个Container时,其实是向某台机器发起请求,请求的是这台机器上的CPU和内存资源。任何一个应用必须运行在一个或多个Container中。在YARN框架中,Resource Manager只负责告诉Application Master哪些Containers可以用,Application Master还需要去找Node Manager请求分配具体的Container。
正如上面提到的,Container是YARN中资源的抽象,它封装了某个节点上的多类资源。当AM向RM申请资源时,RM为AM返回的资源便是用Container表示的。YARN会为每个任务分配一个或多个Container,且该任务只能使用该Container中描述的资源。总的来说,Container对任务运行环境进行抽象,封装CPU、内存等多类资源以及环境变量等任务运行相关的信息。对于资源的表示以内存和CPU为单位,比之前以剩余多少插槽的内存或者CPU数(即slot数)更为合理。因为资源表示成内存和CPU,所以就没有了之前的map slot/reduce slot分开表示而造成集群资源闲置的尴尬情况。另外,Container是YARN为了将来进行资源隔离而提出的一个框架。
既然Container是YARN中资源分配的基本单位,即具有一定的内存以及CPU资源,那么具体对应资源的多少在哪里设置呢?在yarn-site.xml文件中设置,我们将在3.6节详细说明这个XML文件。
2.Node Manager(节点管理器)
Node Manager进程运行在集群中的节点上,管理单个节点上的资源,每个节点都会有自己的Node Manager。Node Manager是一个Slave服务:它负责接收Resource Manager的资源分配请求,分配具体的Container给应用。同时,它还负责监控并报告Container使用信息给Resource Manager。通过和Resource Manager配合,Node Manager负责整个Hadoop集群中的资源分配工作。Resource Manager是一个全局的进程,而Node Manager只是每个节点上的进程,管理这个节点上的资源分配和监控运行节点的健康状态。下面是Node Manager的具体任务列表:
· 接收Resource Manager的请求,分配Container给应用的某个任务。
· 和Resource Manager交换信息以确保整个集群平稳运行。Resource Manager就是通过收集每个Node Manager的报告信息来追踪整个集群健康状态的(如图3-3上关于Node的状态信息),而Node Manager负责监控自身的健康状态。
· 管理每个Container的生命周期。
· 管理每个节点上的日志。
· 处理来自Application Master的命令。
· 执行YARN上面应用的一些额外的服务,例如MapReduce的Shuffle过程。
当一个节点启动时,它会向Resource Manager进行注册并告知Resource Manager自己有多少资源可用(如图3-3上的关于vcores和Memory的状态信息)。在运行期间,通过Node Manager和Resource Manager协同工作,这些信息会不断地被更新并保障整个集群发挥出最佳状态。Node Manager只负责管理自身的Container,它并不知道运行在它上面应用的信息。负责管理应用信息的组件是Application Master。
MapReduce通过slot管理Map和Reduce任务执行所需要的资源,而Node Manager管理抽象容器,这些容器代表着可供特定应用程序使用的针对每个节点的资源。YARN继续使用HDFS层。它的NameNode用于元数据服务,而DataNode用于分散在一个集群中的复制存储服务。
3.Resource Manager(资源管理器)
在YARN中,资源管理由Resource Manager(简称RM)和Node Manager共同完成,其中,Resource Manager中的调度器负责资源的分配,而Node Manager则负责资源的供给和隔离。Resource Manager将某个Node Manager上的资源分配给任务(这就是所谓的“资源调度”)后,Node Manager需按照要求为任务提供相应的资源,甚至保证这些资源应具有独占性,为任务运行提供基础的保证(这就是所谓的“资源隔离”)。
RM控制整个集群并管理应用程序向基础计算资源的分配。RM有以下作用:
(1)处理客户端的请求。
(2)启动或监控Application Master。
(3)监控Node Manager。
(4)资源的分配与调度。
Resource Manager主要有两个组件:Scheduler和Application Manager。Scheduler是一个资源调度器,它主要负责协调集群中各个应用的资源分配,保障整个集群资源的高效率使用。它按照一定的约束条件(例如队列、容量限制等)将集群中的资源分配给各个应用程序(如图3-4中的各个队列)。Scheduler的角色是一个纯调度器,它只负责调度Containers,不会关心应用程序监控及其运行状态等信息。同样,它也不能重启因应用失败或者硬件错误而运行失败的任务。YARN提供了Fair Scheduler和Capacity Scheduler等多租户调度器。关于这两个调度器后面会详细介绍。
另一个组件Application Manager主要负责接收作业的提交请求,为应用分配第一个Container来运行Application Master,还有就是负责监控Application Master,在遇到失败时重启Application Master运行的Container。
4.Application Master(应用程序主控器)
Application Master的主要作用是向Resource Manager申请资源并和Node Manager协同工作来运行应用的各个任务,然后跟踪它们状态及监控各个任务的执行,遇到失败的任务还负责重启它。在YARN中,资源的调度分配由Resource Manager专门进行管理,而每个作业(Job)或应用的管理、监控交由相应的分布在集群中的Application Master,如果某个Application Master失败,Resource Manager还可以重启它,这大大提高了集群的拓展性。这个设计让监测每一个作业子任务(Task)状态的程序分布式化了,更安全了。
图3-3上显示了有多少个应用提交了,多少个应用正在运行,多少个应用已经完成。另外,在这个界面上还可以查到失败的应用和被“杀掉”的应用。应用在YARN中的执行过程可以总结为三步:
(1)应用程序提交。
(2)启动应用的Application Master实例。
(3)Application Master实例管理应用程序的执行。
在一个YARN集群中,首先由应用程序将作业提交(Job Submission),随后Resource Manager分配必要的资源,启动一个Application Master来表示已提交的应用程序。通过使用资源请求协议,Application Master协商处理节点上供应用程序使用的资源容器。在执行应用程序时,Application Master监视容器直到完成。当应用程序完成时,Application Master从Resource Manager注销其容器,应用程序的执行周期就完成了。
在YARN中,Application Master是一个可变更的部分,用户可以对不同的编程模型编写自己的Application Master,让更多类型的编程模型能够运行于Hadoop集群中。在老的框架中,JobTracker(作业追踪器)很大的一个负担就是监控作业下的任务的运行状况,现在,这个部分就扔给Application Master做了,而Resource Manager中的Applications Manager模块,它负责监测Application Master的运行状况,如果出了问题,它会将Application Master在其他机器上重启。
老版本的Hadoop架构只支持MapReduce类型的作业,所以它不是一个通用的框架,因为Hadoop的JobTracker和TaskTracker(任务追踪器)组件都是专门针对MapReduce开发的,它们之间是深度耦合的。YARN解决了这个问题,关于作业或应用的管理都是由Application Master进程负责的,YARN允许我们可以为自己的应用开发自己的Application Master。这样每一个类型的应用都会对应一个Application Master。一个Application Master其实就是一个类库。所以,YARN不再是一个单纯的计算框架,而是一个框架管理器,用户可以将各种各样的计算框架移植到YARN之上,由YARN进行统一管理和资源分配。目前可以支持多种计算框架运行在YARN之上,例如MapReduce、Storm、Spark、Flink等。在YARN中,各种计算框架不再是作为一个服务部署到集群的各个节点上,而是被封装成一个lib存放在客户端,当需要对计算框架进行升级时,只需升级lib库即可。
一个Application Master是一个类库。这里要区分Application Master类库和Application Master实例,一个Application Master类库对应多个实例,就像Java语言中的类和类的实例关系一样。每种类型的应用都会对应着一个Application Master,每个类型的应用都可以启动多个Application Master实例。所以,在YARN中是每个作业都会对应一个Application Master。
3.2.2 YARN执行流程
图3-8展示了应用程序的整个执行流程:
(1)客户端程序向Resource Manager提交应用并请求一个Application Master实例。
(2)Resource Manager找到可以运行一个Container的Node Manager,并在这个Container中启动Application Master实例。
(3)Application Master向Resource Manager进行注册,注册之后客户端就可以查询Resource Manager获得自己Application Master的详细信息,以后就可以和自己的Application Master直接交互了,并且重复4~7步。
(4)在平常的操作过程中,Application Master根据resource-request协议向Resource Manager发送resource-request请求。
(5)当Container被成功分配之后,Application Master通过向Node Manager发送container-launch-specification信息来启动Container,Node Manager为任务设置好运行环境(包括环境变量、JAR包、二进制程序等)。
(6)应用程序的代码在启动的Container中运行,并把运行的进度、状态等信息通过application-specific协议发送给Application Master。
(7)在应用程序运行期间,提交应用的客户端主动和Application Master交流获得应用的运行状态、进度更新等信息,交流的协议也是application-specific协议。
(8)一旦应用程序执行完成并且所有相关工作也已经完成,Application Master向Resource Manager注消然后关闭,用到的Container也都归还给系统。
图3-8 执行过程
YARN的设计目标就是允许我们的各种应用以共享、安全、多租户的形式使用整个集群。并且,为了保证集群资源调度和数据访问的高效性,YARN还必须能够感知整个集群的拓扑结构。为了实现这些目标,Resource Manager的调度器(Scheduler)为应用程序的资源请求定义了一些灵活的协议,通过它就可以对运行在集群中的各个应用做更好的调度,因此,这就诞生了Resource Request和Container。
具体来讲,一个应用先向Application Master发送一个资源请求,然后ApplicationMaster把这个资源请求以resource-request的形式发送给Resource Manager的Scheduler,Scheduler再在这个resource-request中返回分配到的资源描述Container。每个Resource Request可看成是一个可序列化的Java对象,即:
<resource-name, priority, resource-requirement, number-of-containers>
各个字段的含义如下:
· resource-name:资源名称,指的是资源所在的主机(Host)和机架(Rack),还可能是虚拟机。
· priority:资源的优先级。
· resource-requirement:资源的具体需求,指内存和CPU需求的数量。
· number-of-containers:满足需求的Container的集合。
number-of-containers中的Container就是Resource Manager给Application Master分配资源的结果。Container就是授权给应用程序可以使用某个节点机器上CPU和内存的数量。Application Master在得到这些Container后,还需要与Container所在机器的Node Manager交互来启动Container并运行相关任务。当然Container的分配是需要认证的,以防止Application Master自己去请求集群资源。
下面我们以一个Map/Reduce作业运行为例来深入了解整个运行过程。如图3-9所示,YARN的作业运行主要由以下几个步骤组成。
图3-9 YARN作业执行实例
1.作业提交
客户端调用job.waitForCompletion方法,向整个集群提交MapReduce作业(第1步)。资源管理器(Resource Manager)分配作业ID(应用ID)(第2步)。作业的客户端计算输入的split,将作业的资源(包括Jar包、配置文件、split信息)复制给HDFS(第3步)。最后,通过调用资源管理器的submitApplication()函数来提交作业(第4步)。
2.作业初始化
当资源管理器收到submitApplication()的请求时,就将该请求发给Scheduler(调度器),Scheduler分配Container,然后资源管理器在该Container内启动Application Master进程,由Node Manager监控(第5步)。
MapReduce作业的Application Master是一个主类为MRAppMaster的Java应用,它监控作业的进度,得到任务的进度和完成报告(第6步),它通过分布式文件系统得到由客户端计算好的输入split(第7步)。然后为每个输入split创建一个Map任务,根据mapreduce.job.reduces创建Reduce任务对象。
3.任务分配
如果作业很小,Application Master会选择在其自己的JVM中运行任务。如果不是小作业,那么Application Master向Resource Manager请求Container来运行所有的Map和Reduce任务(第8步)。这些请求是通过心跳机制来传输的,包括每个Map任务的数据位置,例如存放输入split的主机名和机架(Rack)。Scheduler利用这些信息来调度任务,尽量将任务分配给存储数据的节点,或者分配给和存放输入split的节点相同机架的节点。
4.任务运行
当一个任务由Resource Manager的Scheduler分配给一个Container后,Application Master通过联系Node Manager来启动Container(第9步)。任务由一个主类为YarnChild的Java应用执行。在运行任务之前首先本地化任务需要的资源,例如作业配置、JAR文件以及分布式缓存的所有文件(第10步)。最后,运行Map或Reduce任务(第11步)。YarnChild运行在一个专用的JVM中,但是YARN不支持JVM重用。
5.进度和状态更新
YARN中的任务将其进度和状态(包括计数器counter)返回给Application Master,客户端每秒(在mapreduce.client.progressmonitor.pollinterval上设置)向Application Master查询进度并展示给用户。
6.作业完成
除了向application Master查询作业进度外,客户端每5分钟都会通过调用waitForCompletion()来检查作业是否完成。时间间隔可以通过mapreduce.client.completion.pollinterval来设置。在作业完成之后,application Master和Container会清理工作状态,OutputCommiter的作业清理方法也会被调用。作业的信息会被作业历史服务器存储以备用户核查。