如果是第一次接触hadoop2.0版本的 Fairshare scheduler , 最好先看一下他的官方文档:
http://hadoop.apache.org/docs/r2.2.0/hadoop-yarn/hadoop-yarn-site/FairScheduler.html
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value> //指定resourcemanager的调度器为 Fairshare 调度器
</property>
<property>
<name>yarn.scheduler.fair.allocation.file</name>
<value>{HADOOP_CONF_DIR}/fair-allocation.xml</value> //fair-allocation.xml 文件是对每一个队列的属性配置
</property>
<property>
<name>yarn.scheduler.fair.user-as-default-queue</name> //如果希望以用户名作为队列,可以将该属性配置为true,默认为true,所以如果不想以用户名为队列的,必须显式的设置成false
<value>false</value>
</property>
<property>
<name>yarn.scheduler.fair.preemption</name> //是否可抢占,如果某个队列配置的最小资源量没有达到,用户提交的作业可以抢占别的队列正在运作的任务的资源。建议不要设置成true,会造成集群资源浪费,并且目前该功能还在进一步完善,默认 false。
<value>false</value>
</property>
<property>
<name>yarn.scheduler.fair.sizebasedweight</name> //以作业的规模大小作为调度的权值,默认为false
<value>true</value>
</property>
<property>
<name>yarn.scheduler.fair.assignmultiple</name> // 一次心跳响应是否允许分配多个container,默认为false
<value>true</value>
</property>
<property>
<name>yarn.scheduler.fair.max.assign</name> //如果一次心跳响应允许分配多个container,一次最多允许分配的container数,默认为-1,没有限制
<value>-1</value>
</property>
<property>
<name>yarn.scheduler.fair.locality.threshold.node</name> // fair 允许等待nodelocal调度的次数,这个配置是集群节点数的比例值。比如说集群100台,为达到某个作业的datalocal调度,允许等待10次。大于10就强制调度
<value>0.1</value>
</property>
<property>
<name>yarn.scheduler.fair.locality.threshold.rack</name> // 类似于yarn.scheduler.fair.locality.threshold.node的配置,这个是为了调度racklocal的任务
<value>0.1</value>
</property>
配置好了yarn-site.xml ,下面配置{HADOOP_CONF_DIR}/fair-allocation.xml
安装官网的配置(注:这个配置有很多坑):
<?xml version="1.0"?>
<allocations>
<queue name="sample_queue"> //队列名
<minResources>10000 mb,0vcores</minResources> //最小资源
<maxResources>90000 mb,0vcores</maxResources> //最大资源
<maxRunningApps>50</maxRunningApps> //可以同时运行的作业数
<weight>2.0</weight> //权值
<schedulingPolicy>fair</schedulingPolicy> //队列内部调度策略,可选的有:fair、fifo、drf 或者 继承该类的子类(org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy)
<queue name="sample_sub_queue"> //队列的子目录
<minResources>5000 mb,0vcores</minResources>
</queue>
</queue>
<user name="sample_user"> //对于特定用户的配置
<maxRunningApps>30</maxRunningApps>
</user>
<userMaxAppsDefault>5</userMaxAppsDefault> //默认的用户最多可以同时运行的任务
</allocations>
官方的配置只是配置了各个队列的资源,fair 调度器有一个很重要的配置就是队列的权限。生产环境下,多用户多队列的权限控制很有必要:
这里有两个坑:
1、子队列的权限可以继承父队列,即使子队列设置自己的权限控制,还是会与父队列的权限取并集。而root队列是所有队列的父队列,他的权限是所有用户都可以提交作业、管理作业。所以,子队列的权限设置是不起作用的。
那如何设置root队列的权限呢?对hadoop2.2.0版本来说,这是个bug: https://issues.apache.org/jira/browse/YARN-1258https://issues.apache.org/jira/browse/YARN-1288
这个问题怎么解决?那就需要将hadoop2.2.0的源码打patch,重新编译。这个会在后面的文章进行介绍。
2、根据官网的配置解析,有一个配置项可以控制队列提交作业权限:aclSubmitApps。我们配置以后发现,用户权限可以使用hadoop queue -showacls 查看,但是正在提交作业的时候,仍然可以提交到没有提交权限的队列。
通过查看源码,发现还有一个配置需要进行配置:aclAdministerApps,这个权限是要大于aclSubmitApps,默认都可以,所以,只配置aclSubmitApps提交作业控制,是不起作用的。
正确的配置:
<?xml version="1.0"?>
<allocations>
<queue name="root">
<minResources>10000mb,10vcores</minResources>
<maxResources>90000mb,100vcores</maxResources>
<maxRunningApps>50</maxRunningApps>
<weight>2.0</weight>
<schedulingMode>fair</schedulingMode>
<aclSubmitApps> </aclSubmitApps>
<aclAdministerApps> </aclAdministerApps>
<queue name="queue1">
<minResources>10000mb,10vcores</minResources>
<maxResources>90000mb,100vcores</maxResources>
<maxRunningApps>50</maxRunningApps>
<weight>2.0</weight>
<schedulingMode>fair</schedulingMode>
<aclAdministerApps>datadev,admins datadev,admins</aclAdministerApps> // 这个配置的格式: user1,user2 [空格] group1,group2
<aclSubmitApps>datadev,admins datadev,admins</aclSubmitApps> //格式同上
</queue>
</queue>
<user name="qingwu.fu">
<maxRunningApps>30</maxRunningApps>
</user>
<userMaxAppsDefault>5</userMaxAppsDefault>
</allocations>