赞
踩
容量调度器是YARN提供的三种调度器中的一种,这种调度器允许多个组织(队列)共享一个Hadoop集群,每个组织(队列)所分配的集群资源是固定的且可配置的。每个组织(队列)内部还可以进一步划分成小队列,小队列之间共享整个组织(队列)的资源。在一个队列中,使用FIFO规则进行任务调度。
容量调度器是Hadoop默认使用的调度器,但是像CDH这样的Hadoop分布式项目,默认使用的公平调度器(Fair Scheduler)。
1. 修改YARN使用的调度器:
位置:$HADOOP_HOME/etc/hadoop/yarn-site.xml
添加配置:
key: yarn.resourcemanager.scheduler.class
value: org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler
2. 定义调度队列
位置:$HADOOP_HOME/etc/hadoop/capacity-scheduler.xml
我本地设置了四个调度队列,它们的结构模型如下:
root
--default
--bigdataU
--azkaban
首先,root队列下分别是三个子队列:default、bigdataU、azkaban,配置队列选项我们可以直接在配置文件中使用
yarn.scheduler.capacity.<queue-path>.<sub-property>作为key,例如,我需要为root.default配置集群资源占比,那么可以写:
- <property>
- <name>yarn.scheduler.capacity.root.default.capacity</name>
- <value>20</value>
- </property>
配置规则讲完了,那么下面就是我们可以为队列配置的信息:
yarn.scheduler.capacity.<queue-path>.capacity:队列在整个组织(队列)的资源占比;
yarn.scheduler.capacity.<queue-path>.maximum-capacity:队列在整个组织(队列)所占资源最大占比,这涉及到调度弹性;
yarn.scheduler.capacity.<queue-path>.state:有两个候选值,RUNNING是正常运行,STOPPED是停止工作,队列如果是STOPPED状态,那么系统将不能提交任务到这个队列以及这个队列的子队列。
其他还有很多配置,如同时运行应用的数量、队列的ACL认证等,详情可以看一下这位仁兄的博客:Capacity Scheduler相关参数
接下来,我把我的配置文件部分信息也发上来:
- <property>
- <name>yarn.scheduler.capacity.root.default.capacity</name>
- <value>20</value>
- </property>
- <property>
- <name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
- <value>45</value>
- </property>
- <property>
- <name>yarn.scheduler.capacity.root.default.state</name>
- <value>RUNNING</value>
- </property>
- <property>
- <name>yarn.scheduler.capacity.root.bigdataU.capacity</name>
- <value>40</value>
- </property>
- <property>
- <name>yarn.scheduler.capacity.root.bigdataU.maximum-capacity</name>
- <value>55</value>
- </property>
- <property>
- <name>yarn.scheduler.capacity.root.bigdataU.state</name>
- <value>RUNNING</value>
- </property>
- <property>
- <name>yarn.scheduler.capacity.root.azkaban.capacity</name>
- <value>40</value>
- </property>
- <property>
- <name>yarn.scheduler.capacity.root.azkaban.maximum-capacity</name>
- <value>45</value>
- </property>
- <property>
- <name>yarn.scheduler.capacity.root.azkaban.state</name>
- <value>RUNNING</value>
- </property>
可以看到,三个子队列分配的资源占比分别是:root.default 20、root.bigdataU 40、root.azkaban 40,这样,在资源足够的情况下三个队列按照1:2:2的比例共享整个集群资源。但是,容量调度器本身提供“弹性队列”的性质,“弹性队列”指的是,如果一个队列的资源不足,同时系统又有空闲资源,那么这个队列所申请的资源可能会超过设定的资源占比。
但是这样存在一个问题,A队列分配了40%的资源,B队列分配了60%的资源,如果A队列此时使用资源很少,B队列资源不够,那么B队列就会抢占A队列的资源,后来,A队列资源不足,虽然A队列资源占比40%,但是实际得到的资源可能不足这个比例,因为资源都被B队列抢走,那么此时A队列的任务只能等待B队列执行完释放资源。
为了避免资源不被其他队列过多侵占,我们可以设置一个队列的最大容量限制(yarn.scheduler.capacity.<queue-path>.maximum-capacity),如上面的配置信息,root.azkaban虽然资源占比40%,但是在某种情况下(该队列资源紧张,集群资源充足),该队列的资源占比最高可以达到45%,要说明的是,如果一个队列没有配置maximum-capacity,那么理论上这个队列可以占用整个集群资源的100%(子队列需要看父队列的资源占比和最大资源占比限制)。
打开YARN的web控制台可以看到,使用的资源调度器是Capacity,主队列root,下面有三个子队列,显示有资源占比、最大资源占比等配置信息。
执行应用的时候,放在哪一个队列取决于应用本身,需要应用自己指定,如果队列不存在,则会抛异常,如果不指定队列,那么应用将被放在队列名为default的默认队列中。如下图我执行一个WordCount任务,但是没有指定使用哪一个队列:
在MapReduce任务中,指定队列可以使用参数mapreduce.job.queuename参数,设置一个队列名。需要注意的是,队列名是队列层级的最后一部分,例如我向指定到队列roor.bigdataU,那么参数需要使用bigdataU。
下面我指定队列再跑一次:
hadoop jar ~/app/hadoop-2.6.0-cdh5.7.0/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.7.0.jar wordcount -D mapreduce.job.queuename=bigdataU /hadoop_test.txt /output/
将一个MapReduce作业放到bigdataU队列中,其参数为:
Used Capacity:实际使用资源占分配资源的比例
Absolute Used Capacity:实际使用资源占整个集群的资源比例
Absolute Capacity:分配资源占比
Absolute Max Capacity:最大分配资源占比
和公平调度器一样,容量调度器允许长时间执行的大任务可以及时完成,同时又允许小任务能在合理的时间内返回结果。
我们可以使用资源占比小的队列专门处理小任务,这样保证在有大任务执行的时候,小任务能够一提交就可以启动。但是由于队列容量是给这个队列专门保留的,因此这个策略会降低整个集群的利用率,也就是说,相对于FIFO,大任务执行的时间会变长。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。