如 fair-scheduler.xml 配置如下,root 下有 aa 和 bb 队列,bb 队列有 bbsub1 和 bbsub2 两个字队列。
<?xml version="1.0"?>
<allocations>
<queue name="aa">
<weight>2</weight>
<schedulingPolicy>fair</schedulingPolicy>
<minResources>800000mb,200vcores</minResources>
<maxResources>2000000mb,500vcores</maxResources>
<maxRunningApps>30</maxRunningApps>
</queue>
<queue name="bb">
<weight>2</weight>
<schedulingPolicy>fair</schedulingPolicy>
<minResources>800000mb,200vcores</minResources>
<maxResources>2000000mb,500vcores</maxResources>
<maxRunningApps>30</maxRunningApps>
<queue name="bbsub1">
<weight>2</weight>
<schedulingPolicy>fair</schedulingPolicy>
<minResources>800000mb,200vcores</minResources>
<maxResources>2000000mb,500vcores</maxResources>
<maxRunningApps>30</maxRunningApps>
</queue>
<queue name="bbsub2">
<weight>2</weight>
<schedulingPolicy>fair</schedulingPolicy>
<minResources>800000mb,200vcores</minResources>
<maxResources>2000000mb,500vcores</maxResources>
<maxRunningApps>30</maxRunningApps>
</queue>
</queue>
<queueMaxAMShareDefault>0.5</queueMaxAMShareDefault>
<userMaxAppsDefault>500</userMaxAppsDefault>
<queuePlacementPolicy>
<rule name="specified" create="false"/>
<rule name="primaryGroup" create="false"/>
<rule name="default" />
</queuePlacementPolicy>
</allocations>
我们有三个规则,第1个规则是提交到用户指定的队列。第 2 个是提交到 primaryGroup 的队列。
我们新建 Hadoop 用户组 aa,在 aa 用户组下得用户自动都能分配到 aa 队列。
我们想使用 bb 子队列的用户也能自动分配到响应的队列,发现不行。
原因分析:
primaryGroup: the app is placed into a queue with the name of the primary group of the user who submitted it. Periods in the group name will be replaced with “_dot_”, i.e. the queue name for group “one.two” is “one_dot_two”.
官网上有这样的解释,用户的程序会提交到用户的主组里。如果组名里包含 ‘.’,会被替换成 “dot”。如组名 “one.two” 会提交到 “one_dot_two” 这个队列里。
主组是一个用户可能属于多个组,只有第1个组成为主组,也就是 primary group.
源代码分析:
org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.QueuePlacementRule
public static class PrimaryGroup extends QueuePlacementRule {
@Override
protected String getQueueForApp(String requestedQueue, String user,
Groups groups, Map<FSQueueType, Set<String>> configuredQueues)
throws IOException {
return "root." + cleanName(groups.getGroups(user).get(0));
}
@Override
public boolean isTerminal() {
return create;
}
}
protected String cleanName(String name) {
if (name.contains(".")) {
String converted = name.replaceAll("\\.", "_dot_");
LOG.warn("Name " + name + " is converted to " + converted
+ " when it is used as a queue name.");
return converted;
} else {
return name;
}
}
代码非常简单,先拿到用户对应的组名,然后调用 cleanName
clean 下。也就是返回的队列名里只能是 “root.” 后的队列名,不能是再下一层队列。