From 8c8ef2f444ec6f7608e3fabff5f1da87f1736d2d Mon Sep 17 00:00:00 2001 From: Inigo Goiri Date: Wed, 6 May 2020 13:22:54 -0700 Subject: [PATCH] YARN-9017. PlacementRule order is not maintained in CS. Contributed by Bilwa S T. (cherry picked from commit 35010120fbbcad8618f99abf7130e53f98879a33) --- .../scheduler/capacity/CapacityScheduler.java | 7 ++- .../CapacitySchedulerConfigValidator.java | 4 +- .../placement/TestPlacementManager.java | 49 ++++++++++++++++--- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java index a95cca2a96..890334f17b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java @@ -703,8 +703,11 @@ public void updatePlacementRules() throws IOException { Set distinguishRuleSet = CapacitySchedulerConfigValidator .validatePlacementRules(placementRuleStrs); - // add UserGroupMappingPlacementRule if absent - distinguishRuleSet.add(YarnConfiguration.USER_GROUP_PLACEMENT_RULE); + // add UserGroupMappingPlacementRule if empty,default value of + // yarn.scheduler.queue-placement-rules is user-group + if (distinguishRuleSet.isEmpty()) { + distinguishRuleSet.add(YarnConfiguration.USER_GROUP_PLACEMENT_RULE); + } placementRuleStrs = new ArrayList<>(distinguishRuleSet); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacitySchedulerConfigValidator.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacitySchedulerConfigValidator.java index 1c598efd8d..c3b4df4efd 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacitySchedulerConfigValidator.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacitySchedulerConfigValidator.java @@ -28,7 +28,7 @@ import java.io.IOException; import java.util.Collection; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; public final class CapacitySchedulerConfigValidator { @@ -58,7 +58,7 @@ public static boolean validateCSConfiguration( public static Set validatePlacementRules( Collection placementRuleStrs) throws IOException { - Set distinguishRuleSet = new HashSet<>(); + Set distinguishRuleSet = new LinkedHashSet<>(); // fail the case if we get duplicate placementRule add in for (String pls : placementRuleStrs) { if (!distinguishRuleSet.add(pls)) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/placement/TestPlacementManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/placement/TestPlacementManager.java index 083af3bffb..22a9125576 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/placement/TestPlacementManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/placement/TestPlacementManager.java @@ -18,7 +18,6 @@ package org.apache.hadoop.yarn.server.resourcemanager.placement; -import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.server.resourcemanager.MockRM; @@ -28,7 +27,9 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration; import org.apache.hadoop.yarn.util.Records; +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import java.util.ArrayList; @@ -49,20 +50,22 @@ public class TestPlacementManager { public static final String PARENT_QUEUE = "c"; private MockRM mockRM = null; - - private static final long CLUSTER_TIMESTAMP = System.currentTimeMillis(); + private CapacitySchedulerConfiguration conf; private String getQueueMapping(String parentQueue, String leafQueue) { return parentQueue + DOT + leafQueue; } - @Test - public void testPlaceApplicationWithPlacementRuleChain() throws Exception { - CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration(); + @Before + public void setup() { + conf = new CapacitySchedulerConfiguration(); setupQueueConfiguration(conf); conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, ResourceScheduler.class); + } + @Test + public void testPlaceApplicationWithPlacementRuleChain() throws Exception { mockRM = new MockRM(conf); CapacityScheduler cs = (CapacityScheduler) mockRM.getResourceScheduler(); mockRM.start(); @@ -112,4 +115,38 @@ public void testPlaceApplicationWithPlacementRuleChain() throws Exception { } } + @Test + public void testPlacementRuleUpdationOrder() throws Exception { + List queueMappings = new ArrayList<>(); + QueueMapping userQueueMapping = QueueMappingBuilder.create() + .type(MappingType.USER).source(USER1) + .queue(getQueueMapping(PARENT_QUEUE, USER1)).build(); + UserGroupMappingPlacementRule ugRule = new UserGroupMappingPlacementRule( + false, Arrays.asList(userQueueMapping), null); + + // Configure placement rule + conf.set(YarnConfiguration.QUEUE_PLACEMENT_RULES, ugRule.getName()); + queueMappings.add(userQueueMapping); + conf.setQueueMappings(queueMappings); + + mockRM = new MockRM(conf); + CapacityScheduler cs = (CapacityScheduler) mockRM.getResourceScheduler(); + mockRM.start(); + PlacementManager pm = cs.getRMContext().getQueuePlacementManager(); + + // As we are setting placement rule, It shouldn't update default + // placement rule ie user-group. Number of placemnt rules should be 1. + Assert.assertEquals(1, pm.getPlacementRules().size()); + // Verifying if placement rule set is same as the one we configured + Assert.assertEquals(ugRule.getName(), + pm.getPlacementRules().get(0).getName()); + } + + @After + public void tearDown() { + if (null != mockRM) { + mockRM.stop(); + } + } + } \ No newline at end of file