YARN (Yet Another Resource Negotiator)字面翻译是“一个资源调度者”。YARN在Hadoop里是负责资源分配的。你提交了一个MapReduce的job给Hadoop集群。Map 和 Reduce 分给谁去执行,执行失败怎么办?如果多个用户同时提交job,资源分给谁去执行?这些问题都是由YARN来负责解决的。
在YARN之前,MapReduce的job调度是整个集群有一个JobTracker,其他全部是TaskerTracker。JobTracker负责接收用户提交的任务,管理整个集群的资源,根据负载和请求分配task给TaskerTracker去运行,并监控每一个tasker的进度,重启失败的task。每个Node上的资源被固定分为map slot和reduce slot。map slot只能执行map任务,reduce slot只能执行reduce任务。即使当前map任务很多,没有reduce任务,这些被预先分配的reduce slot也不能被借用。可以看到在YARN之前的资源分配主要有以下几个缺点:
1. JobTracker的任务太重
2. 资源没有被有效分配

YARN之前的JobTracker有点像创业公司的小老板,事无巨细,知道每个员工干什么。但是当公司规模达到几千人的时候,这显然是不可能的。所以公司会设立项目组,每个项目有项目负责人,老板让他运行一个项目并对该项目负责。他向老板申请资源并运行项目。老板要做的就是在各个项目负责人向自己申请资源的时候负责协调资源,人手有限的情况的如何让各个项目有计划的顺利推行。

YARN里的一些基本概念:

Container

Container 是YARN里的资源管理单元。Container是一个资源集合,它定义了一个封闭的资源空间,比如内存多大,cpu几个核的信息。Container也是Task运行的地方。Task只能占用Container定义的资源来运行。Hadoop集群里的一个Node可以包含多个Container。比如我们之前说的MapReduce job,其中的Mapper,和Reducer都是一个task,他们都是独立运行在一个Container里的。
如何配置Container的大小呢?
你可以在yarn-site.xml添加下边的配置让YARN自动配置我们的资源:


 <property>
          <name>yarn.nodemanager.resource.detect-hardware-capabilities</name>
          <value>true</value>
 </property>

如果你想自己配置每个Node的container资源的使用,你也可以通过下边的配置来实现。注意你不需要指定每个container的固定资源大小,而是只要配置该Node内所有Container可以使用的资源总和。以及每个Container可以分配的最小和最大资源是多少。同样这些配置也是在yarn-site.xml里的。


 <property>
          <name>yarn.nodemanager.resource.memory-mb</name>
          <value>4096</value>
 </property>
 <property>
          <name>yarn.scheduler.minimum-allocation-mb</name>
          <value>512</value>
 </property>
 <property>
          <name>yarn.scheduler.maximum-allocation-mb</name>
          <value>4096</value>
 </property>

上边的配置是一个Node里允许所有的container总共使用的内存不超过4096M,一个container最小的内存分配粒度是512M,最大是4096M。同样也有对于cpu核数的配置:


 <property>
          <name>yarn.nodemanager.resource.cpu-vcores</name>
          <value>8</value>
 </property>
 <property>
          <name>yarn.scheduler.minimum-allocation-vcores</name>
          <value>1</value>
 </property>
 <property>
          <name>yarn.scheduler.maximum-allocation-vcores</name>
          <value>2</value>
 </property>

Node Manager

Node Manager在每一个Node上都会运行一个,它的主要工作就是管理运行在这个Node上的Container,包括给Resource Manager汇报Node上的可用资源。以及根据指示在Container上启动task,并监控task的运行。如果task运行时占用的资源超过container的定义,则kill掉这个task。

Resource Manager

一个集群里只有一个运行着的Resource Manager。它负责协调整个集群的container,使得在多应用竞争集群资源的时候,集群也能尽可能高效的对外提供服务。对于资源竞争Resource Manager有多种策略来应对,下一节我们会详细介绍。所以ResouceManager只负责找一个container来启动client提交的主程序(Application Master),Application Master来向Resource Manager申请资源,执行自己的业务逻辑。Applicaiton Master自己在分配来的container里执行自己的task。因为Resource Manager并不关系具体的业务逻辑,所以使得YARN更加通用,不光是MapReduce,还有Spark,Pig,Hive等都可以用YARN来完成自己的分布式计算。
ResourceManager里有整个集群的信息,比如在MapReduce的任务里,我们希望每一个Mapper运行在存储了对应HDFS文件block的node上。当MapReduce job 的 Application Master向ResourceManager请求资源时,它知道HDFS文件的每个block存储在集群哪个Node上,而且它向Resource Manager申请资源时是可以指定hostname的。一个具体的资源请求信息包含下边的信息:


ContainerRequest(Resource capability, String[] nodes,String[] racks, Priority priority, boolean relaxLocality)
{
                ...
}
//一个resource,包含memroy和cpu核数
public static Resource newInstance(int memory, int vCores)
{
                ...
}

上边是YARN的部分源码,可以看到一个Container Request包含Resource(也就是指定container的内存大小和cpu核数),nodes数组指定了希望container被分配的机器。racks数组指定希望被分配的racks。priority指定了这个请求的优先级。relaxLocality为true,表示你对host和rack的指定也不是那么严格,如果你希望的host和rack都没有可用资源,可以分配到其他Node。
更具体的说,一个Resource Manager有着一下功能:
1. 接收客户程序提交Applicaiton,终止Applicaiton,获取任务队列信息,集群状态信息等。
2. 管理员可以通过Resouce Manager 配置YARN集群,比如刷新node list,配置任务队列等。
3. 接收NodeManager发来的心跳信息,如果一个Node一段时间内没有发送,则认为该Node失效。
4. 接收ApplicationMaster发来的分配或者释放container的请求。
5. 接收ApplicationMaster发来的心跳信息,如果一个ApplicaitonMaster没有正常终止也没有按时发来心跳信息,Resource Manager会通知NodeManager收回所有分配给这个ApplicaitonMaster的资源。然后会重新找一个container来运行ApplicationMaster。
6. 通过各种可配置的sheduler,为多个同时竞争运行的applicaiton进行资源分配。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: