diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java index bca0ea4..686d6d6 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java @@ -24,6 +24,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.Iterator; import java.util.concurrent.CopyOnWriteArrayList; import javax.xml.parsers.ParserConfigurationException; @@ -39,13 +41,11 @@ import com.google.common.base.CharMatcher; import com.google.common.annotations.VisibleForTesting; -import java.util.Iterator; -import java.util.Set; import org.apache.hadoop.yarn.api.records.Resource; + /** * Maintains a list of queues as well as scheduling parameters for each queue, * such as guaranteed share allocations, from the fair scheduler config file. - * */ @Private @Unstable @@ -79,7 +79,30 @@ public void initialize(Configuration conf) throws IOException, // Create the default queue getLeafQueue(YarnConfiguration.DEFAULT_QUEUE_NAME, true); } - + + /** + * Recursively check whether parent policies of a queue are allowed. + * + * @param parent the parent queue + * @param policy the policy of current queue + */ + private void checkIfParentPoliceAllowed(FSQueue parent, + SchedulingPolicy policy) throws AllocationConfigurationException { + if (parent == null ) { + return; + } + + Set policies = policy.allowParentPolicies(); + + if (policies.contains(parent.getPolicy().getName())) { + checkIfParentPoliceAllowed(parent.getParent(), parent.getPolicy()); + } else { + throw new AllocationConfigurationException("Parent scheduling policy " + + "can only be in " + policies + " if the " + + "scheduling policy of current queue is" + policy.getName()); + } + } + /** * Get a leaf queue by name, creating it if the create param is true and is necessary. * If the queue is not or can not be a leaf queue, i.e. it already exists as a @@ -191,6 +214,15 @@ FSQueue createQueue(String name, FSQueueType queueType) { FSQueue queue = null; if (parent != null) { + // check parent policies + try { + checkIfParentPoliceAllowed(parent, + scheduler.getAllocationConfiguration(). + getSchedulingPolicy(name)); + } catch (AllocationConfigurationException ex) { + LOG.error("Can't create queue '" + name + "'.", ex); + return null; + } // Now that we know everything worked out, make all the queues // and add them to the map. queue = createNewQueues(queueType, parent, newQueueNames); @@ -267,6 +299,8 @@ private FSQueue createNewQueues(FSQueueType queueType, FSParentQueue parent = topParent; FSQueue queue = null; + + while (i.hasNext()) { FSParentQueue newParent = null; String queueName = i.next(); @@ -480,6 +514,18 @@ private String ensureRootPrefix(String name) { public void updateAllocationConfiguration(AllocationConfiguration queueConf) { // Create leaf queues and the parent queues in a leaf's ancestry if they do not exist synchronized (queues) { + // Set scheduling policies for root and root.default + for (FSQueue queue : queues.values()) { + try { + SchedulingPolicy policy = + queueConf.getSchedulingPolicy(queue.getName()); + queue.setPolicy(policy); + } catch (AllocationConfigurationException ex) { + LOG.warn("Cannot apply configured scheduling policy to queue " + + queue.getName(), ex); + } + } + for (String name : queueConf.getConfiguredQueues().get( FSQueueType.LEAF)) { if (removeEmptyIncompatibleQueues(name, FSQueueType.LEAF)) { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/SchedulingPolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/SchedulingPolicy.java index 9eda46c..4adf5f0 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/SchedulingPolicy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/SchedulingPolicy.java @@ -31,6 +31,7 @@ import java.util.Collection; import java.util.Comparator; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @Public @@ -191,4 +192,10 @@ public abstract boolean checkIfUsageOverFairShare( public abstract Resource getHeadroom(Resource queueFairShare, Resource queueUsage, Resource maxAvailable); + /** + * Return parent policies allowed based on the current policy. + * + * @return policies allowed + */ + public abstract Set allowParentPolicies(); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/DominantResourceFairnessPolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/DominantResourceFairnessPolicy.java index ad41b11..100523f 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/DominantResourceFairnessPolicy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/DominantResourceFairnessPolicy.java @@ -20,6 +20,8 @@ import java.util.Collection; import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceStability.Unstable; @@ -203,4 +205,11 @@ private int compareShares(ResourceWeights shares1, ResourceWeights shares2, return 0; } } + + @Override + public Set allowParentPolicies() { + Set policies = new HashSet<>(); + policies.add(DominantResourceFairnessPolicy.NAME); + return policies; + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FairSharePolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FairSharePolicy.java index d47ea07..2b9c36c 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FairSharePolicy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FairSharePolicy.java @@ -20,6 +20,8 @@ import java.io.Serializable; import java.util.Collection; import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceStability.Unstable; @@ -178,4 +180,12 @@ public boolean checkIfUsageOverFairShare(Resource usage, Resource fairShare) { public byte getApplicableDepth() { return SchedulingPolicy.DEPTH_ANY; } + + @Override + public Set allowParentPolicies() { + Set policies = new HashSet<>(); + policies.add(FairSharePolicy.NAME); + policies.add(DominantResourceFairnessPolicy.NAME); + return policies; + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FifoPolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FifoPolicy.java index 3e2cb9f..72757972 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FifoPolicy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FifoPolicy.java @@ -20,6 +20,8 @@ import java.io.Serializable; import java.util.Collection; import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceStability.Unstable; @@ -132,4 +134,14 @@ public Resource getHeadroom(Resource queueFairShare, public byte getApplicableDepth() { return SchedulingPolicy.DEPTH_LEAF; } + + @Override + public Set allowParentPolicies() { + Set policies = new HashSet<>(); + // Fifo policy can only be in a leaf queue, so it is not allowed + // as a parent queue policy. + policies.add(FairSharePolicy.NAME); + policies.add(DominantResourceFairnessPolicy.NAME); + return policies; + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java index b1e412b..e2cc552 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java @@ -5096,4 +5096,35 @@ public void testUpdateDemand() throws IOException { Resources.equals(bQueue.getDemand(), maxResource)); } + @Test + public void testSchedulingPolicyViolation() throws IOException { + conf.set(FairSchedulerConfiguration.ALLOCATION_FILE, ALLOC_FILE); + PrintWriter out = new PrintWriter(new FileWriter(ALLOC_FILE)); + out.println(""); + out.println(""); + out.println(""); + out.println("fair"); + out.println(" "); + out.println(" drf"); + out.println(" "); + out.println(""); + out.println("drf" + + ""); + out.println(""); + out.close(); + + scheduler.init(conf); + scheduler.start(); + scheduler.reinitialize(conf, resourceManager.getRMContext()); + + FSQueue child = scheduler.getQueueManager().getQueue("child"); + assertNull("Child queue should be null since it isn't allowed to be 'drf' " + + "policy if its parent is 'fair' policy ", child); + + // dynamic queue + FSQueue dynamicQueue = scheduler.getQueueManager(). + getLeafQueue("dynamicQueue", true); + assertNull("Dynamic queue should be null since it isn't allowed to be 'drf'" + + " policy if its parent is 'fair' policy ", dynamicQueue); + } }