YARN ResourceManager调度器分析

YARN是Hadoop新版中的资源控制框架。本文旨在深入剖析ResourceManager的调度器,探讨三种调度器的设计侧重,最后给出一些配置建议和参数解释。
本文分析基于CDH4.2.1。调度器这个部分目前还在快速变化之中。例如,CPU资源分配等特性在不就的将来就会加入。
为了方便查阅源代码,原代码位置使用[类名:行号]方式表示。
名词解释:
ResourceManager:以下简称RM。YARN的中控模块,负责统一规划资源的使用。
NodeManager:以下简称NM。YARN的资源结点模块,负责启动管理container。
ApplicationMaster:以下简称AM。YARN中每个应用都会启动一个AM,负责向RM申请资源,请求NM启动container,并告诉container做什么事情。
Container:资源容器。YARN中所有的应用都是在container之上运行的。AM也是在container上运行的,不过AM的container是RM申请的。
1.RM中的调度器
ResourceManager是YARN资源控制框架的中心模块,负责集群中所有的资源的统一管理和分配。它接收来自NM的汇报,建立AM,并将资源派送给AM。整体的RM的框架可以参考:RM总体架构

最初的hadoop的版本只有FifoScheduler(先进先出调度器)。当Hadoop集群在大规模使用的时候,如何整合资源和分配资源就是一个迫切的需求。对此,Yahoo!和facebook先后开发了CapacityScheduler(容量调度器)和FairScheduler(公平调度器)。在新版本中,这两个调度器在保持核心算法的基础上,也被重新开发了一次。(实际上所有整个YARN的代码都是重写的…)
2.调度器的接口
首先来了解一下调度器的工作方式和对外暴露的接口:[ResourceScheduler:36]
一个完整的调度器在内存中都会维护一个队列,应用,NM,Container的关系。同时,一个调度器也是一个事件处理器,通过RM的异步的事件调用机制知晓外部的发生的事情。要跟外部交互也要发送相应的事件。调度器一共要处理6个调度事件。Node_ADDED/NODE_REMOVED/NODE_UPDATE/APP_ADDED/APP_REMOVED/CONTAINER_EXPIRED
AM会告诉调度器一些资源申请的请求和已经使用完的container的列表,然后获取到已经在NODE_UPDATE分配给这个应用的container的分配。
可以看到调度器接受资源的申请和分配资源这个动作是异步的。
3.资源分配模型
无论FifoScheduler,CapacityScheduler和FairScheduler的核心资源分配模型都是一样的。
调度器维护一群队列的信息。用户可以向一个或者多个队列提交应用。每次NM心跳的时候,调度器,根据一定的规则选择一个队列,再在队列上选择一个应用,尝试在这个应用上分配资源。不过,因为一些参数限制了分配失败,就会继续选择下一个应用。在选择了一个应用之后,这个应用对应也会有很多的资源申请的请求。调度器会优先匹配本地资源是申请请求,其次是同机架的,最后的任意机器的。
 
总的来说,3种调度器就是在回答如何选择一个队列,在一个队列上如何选择一个应用的问题。
当然,实际上,比起简单的FifoScheduler。CapacityScheduler和FairScheduler还有更多新奇好玩的特性。
4.调度器比较
我们先比较下3种调度器。
调度器FifoSchedulerCapacitySchedulerFairScheduler
设计目的最简单的调度器,易于理解和上手
多用户的情况下,最大化集群的吞吐和利用率
多用户的情况下,强调用户公平地贡献资源
队列组织方式单队列树状组织队列。无论父队列还是子队列都会有资源参数限制,子队列的资源限制计算是基于父队列的。应用提交到叶子队列。树状组织队列。但是父队列和子队列没有参数继承关系。父队列的资源限制对子队列没有影响。应用提交到叶子队列。
资源限制无父子队列之间有容量关系。每个队列限制了资源使用量,全局最大资源使用量,最大活跃应用数量等。每个叶子队列有最小共享量,最大资源量和最大活跃应用数量。用户有最大活跃应用数量的全局配置。
队列ACL限制可以限制应用提交权限可以限制应用提交权限和队列开关权限,父子队列间的ACL会继承。可以限制应用提交权限,父子队列间的ACL会继承。但是由于支持客户端动态创建队列,需要限制默认队列的应用数量。目前,还看不到关闭动态创建队列的选项。
队列排序算法无按照队列的资源使用量最小的优先根据公平排序算法排序
应用选择算法先进先出先进先出先进先出或者公平排序算法
本地优先分配支持支持支持
延迟调度不支持不支持支持
资源抢占不支持不支持支持,看到代码中也有实现。但是,由于本特性还在开发阶段,本文没有真实试验。
简单总结下:
FifoScheduler:最简单的调度器,按照先进先出的方式处理应用。只有一个队列可提交应用,所有用户提交到这个队列。可以针对这个队列设置ACL。没有应用优先级可以配置。
CapacityScheduler:可以看作是FifoScheduler的多队列版本。每个队列可以限制资源使用量。但是,队列间的资源分配以使用量作排列依据,使得容量小的队列有竞争优势。集群整体吞吐较大。延迟调度机制使得应用可以放弃,夸机器或者夸机架的调度机会,争取本地调度。
FairScheduler:多队列,多用户共享资源。特有的客户端创建队列的特性,使得权限控制不太完美。根据队列设定的最小共享量或者权重等参数,按比例共享资源。延迟调度机制跟CapacityScheduler的目的类似,但是实现方式稍有不同。资源抢占特性,是指调度器能够依据公平资源共享算法,计算每个队列应得的资源,将超额资源的队列的部分容器释放掉的特性。
5.本地优化与延迟调度
我们解释一下什么是本地优化和延迟调度。
Hadoop是构建在以hdfs为基础的文件系统之上的。YARN所运行的应用的绝大部分输入都是hdfs上的文件。而hdfs上的文件的是分块多副本存储的。假设文件系统的备份因子是3。则每一个文件块都会在3个机器上有副本。在YARN运行应用的时候,AM会将输入文件进行切割,然后,AM向RM申请的container来运行task来处理这些被切割的文件段。
假如输入文件在ABC三个机器上有备份,那如果AM申请到的container在这3个机器上的其中一个,那这个task就无须从其它机器上传输要处理的文件段,节省网络传输。这就是Hadoop的本地优化。所以Hadoop的文件备份数量除了和数据安全有关,还对应用运行效率有莫大关系。
YARN的实现本地优化的方式是AM给RM提交的资源申请的时候,会同时发送本地申请,机架申请和任意申请。然后,RM的匹配这些资源申请的时候,会先匹配本地申请,再匹配机架申请,最后才匹配任意申请。关于AM资源申请机制可以参考:ContainerAlloctor分析
而延迟调度机制,就是调度器在匹配本地申请失败的时候,匹配机架申请或者任意申请成功的时候,允许略过这次的资源分配,直到达到延迟调度次数上限。CapacityScheduler和FairScheduler在延迟调度上的实现稍有不同,前者的调度次数是根据规则计算的,后者的调度次数通过配置指定的,但实际的含义是一样的。
6.参数配置
要彻底理解各个参数配置中关系,就不能忽略掉调度器的调度算法和调度细节。
[b]6.1.调度器的集群配置[/b]
以下是和调度器密切相关的集群配置
配置文件
配置项

含义 
mapred-site.xml
yarn.app.mapreduce.am.resource.mb
1024
ApplicationMaster的container占用的内存大小 
mapreduce.map.memory.mb
mapreduce.reduce.memory.mb
512/512
map/reduce阶段申请的container的内存的大小 
mapreduce.map.java.opts
mapreduce.reduce.java.opts 
用户设定的map/reduce阶段申请的container的JVM参数。最大堆设定要比申请的内存少一些,用于JVM的非堆部分使用。 
mapreduce.admin.map.child.java.opts
mapreduce.admin.reduce.child.java.opts 
-Xmx500m
管理员设定的map/reduce阶段申请的container的默认JVM启动参数。启动container的命令行会先连接管理员设定参数,然后再连接用户设定参数。 
yarn-site.xml
yarn.nodemanager.vmem-pmem-ratio
4.0
container可使用的虚拟映射地址是物理内存的多少倍。 
yarn.scheduler.minimum-allocation-mb
512
container最小可申请的内存。在调度器中,很多资源计算部分会转化为这个最小值的N倍进行计算。所以,设定可分配内存等资源的时候,最好是刚好为这个最小值的倍数。 
yarn.scheduler.maximum-allocation-mb
2048
container最多可申请的内存数量 
yarn.resourcemanager.scheduler.class
FairScheduler
/CapacityScheduler
ResourceManager加载的调度器类实例 
yarn-site.private.xml
yarn.nodemanager.resource.memory-mb
4096
每个nodemanager可分配的内存总量

[b]6.2. 容量调度器[/b]
容量调度器(CapacityScheduler),由Yahoo!最初开发,被设计出来使得hadoop应用能够被多用户使用,且最大化整个集群资源的吞吐量。[b]6.2.1. 容量调度器的配置[/b]
在hadoop集群配置中启动容量调度器之后,调度器会从classpath中加载capacity-scheduler.xml文件,完成容量调度器的初始化。总结起来有如下特性:
1) 动态更新配置:容量调度器的配置文件在运行时可以随时重新加载来调整分配参数。除非重启ResourceManager,否则队列只能添加不能删除,但是允许关闭。修改配置文件后,使用以下命令可以刷新配置。
yarn rmadmin -refreshQueues
2) 树形组织队列:容量调度器的队列是按照树形结构组织的。根队列只有一个root队列。子队列分享父队列的资源。每个队列设定一个容量值代表可使用父队列的容量值,容量值会影响队列的排序。父队列的所有子队列的容量相加一定是100,否则加载失败。还有一个最大容量值表示子队列绝对不会超过的使用上限。
3) 队列应用限制:队列可以设定最大提交的应用数量和AM占用资源的百分比。AM占用资源的百分比这个配置是用来计算队列的最大活跃应用数量。这里有个小问题。调度器中最大活跃应用数量=AM占用资源的百分比*队列最大可使用资源量/最小的container分配额度。但是我们在mapred-site.xml中会配置AM的内存额度会比最小container分配额度大,造成最大活跃应用数量虚高(可以理解,如果YARN加入不同的计算框架,AM的分配会不一致,所以这里使用最小container分配额度来计算。但是,如果是这样的话,应该直接计算AM的内存使用量来控制)。
4) 用户参数限制:用户可以提交应用到多个队列。不同队列间用户的应用运行情况,不相互影响。用户在队列中最大可占用资源受两个参数控制,一个是单用户占据队列的百分比上限,一个是单用户内存使用上限。具体参看下面的参数表。
5)资源分配选择:不同队列之间,按照队列的资源使用比排序。同一队列中的应用按照应用id排序,也就是先进先出。
6)延迟调度:当调度次数小于本地延迟调度次数的时候不接受机架调度。本地延迟调度次数,由yarn.scheduler.capacity.node-locality-delay配置,默认是-1,不开启延迟调度。官方文档中没有提及这个参数。而任意调度的延迟调度上限是应用申请的机器的数量,不能配置。
 

0 个评论

要回复文章请先登录注册