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/fair/FairScheduler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java index 20d1afe0b6b..61c901cbe99 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java @@ -94,6 +94,7 @@ import org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator; import org.apache.hadoop.yarn.util.resource.DominantResourceCalculator; import org.apache.hadoop.yarn.util.resource.ResourceCalculator; +import org.apache.hadoop.yarn.util.resource.ResourceUtils; import org.apache.hadoop.yarn.util.resource.Resources; import java.io.IOException; @@ -1417,7 +1418,7 @@ private void initScheduler(Configuration conf) throws IOException { } if (continuousSchedulingEnabled) { - // Contiuous scheduling is deprecated log it on startup + // Continuous scheduling is deprecated log it on startup LOG.warn("Continuous scheduling is turned ON. It is deprecated " + "because it can cause scheduler slowness due to locking issues. " + "Schedulers should use assignmultiple as a replacement."); @@ -1530,6 +1531,12 @@ public void reinitialize(Configuration conf, RMContext rmContext) } catch (Exception e) { LOG.error("Failed to reload allocations file", e); } + try { + refreshMaximumAllocation( + ResourceUtils.fetchMaximumAllocationFromConfig(conf)); + } catch (Exception e) { + LOG.error("Failed to refresh maximum allocation", e); + } } @Override diff --git a/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 b/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 9120d3a6cc1..a54078dd26b 100644 --- a/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 +++ b/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 @@ -18,6 +18,9 @@ package org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair; +import static org.apache.hadoop.yarn.util.resource.ResourceUtils + .MAXIMUM_ALLOCATION; +import static org.apache.hadoop.yarn.util.resource.ResourceUtils.UNITS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; @@ -28,9 +31,11 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -53,6 +58,7 @@ import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; import org.apache.hadoop.net.NetworkTopology; import org.apache.hadoop.security.GroupMappingServiceProvider; +import org.apache.hadoop.yarn.LocalConfigurationProvider; import org.apache.hadoop.yarn.MockApps; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationId; @@ -100,8 +106,6 @@ import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode; import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeResourceUpdateEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.AbstractYarnScheduler; - - import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueMetrics; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerApplicationAttempt; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNode; @@ -274,8 +278,8 @@ public void testMinZeroResourcesSettings() throws IOException { Assert.assertEquals(0, scheduler.getMinimumResourceCapability().getVirtualCores()); Assert.assertEquals(512, scheduler.getIncrementResourceCapability().getMemorySize()); Assert.assertEquals(2, scheduler.getIncrementResourceCapability().getVirtualCores()); - } - + } + @Test public void testAggregateCapacityTracking() throws Exception { scheduler.init(conf); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairSchedulerWithMultiResourceTypes.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairSchedulerWithMultiResourceTypes.java new file mode 100644 index 00000000000..78376b6b0a1 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairSchedulerWithMultiResourceTypes.java @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; +import org.apache.hadoop.yarn.LocalConfigurationProvider; +import org.apache.hadoop.yarn.api.records.Resource; +import org.apache.hadoop.yarn.api.records.ResourceInformation; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.event.AsyncDispatcher; +import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; +import org.apache.hadoop.yarn.server.resourcemanager.MockRM; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueMetrics; +import org.apache.hadoop.yarn.util.resource.ResourceUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import static org.apache.hadoop.yarn.util.resource.ResourceUtils.MAXIMUM_ALLOCATION; +import static org.apache.hadoop.yarn.util.resource.ResourceUtils.UNITS; +import static org.junit.Assert.assertEquals; + +public class TestFairSchedulerWithMultiResourceTypes extends FairSchedulerTestBase { + + private static final String A_CUSTOM_RESOURCE = "a-custom-resource"; + + private static class CustomResourceTypesConfigurationProvider + extends LocalConfigurationProvider { + + @Override + public InputStream getConfigurationInputStream(Configuration bootstrapConf, + String name) throws YarnException, IOException { + if (YarnConfiguration.RESOURCE_TYPES_CONFIGURATION_FILE.equals(name)) { + return new ByteArrayInputStream(( + "\n" + + " \n" + + " yarn.resource-types\n" + + " " + A_CUSTOM_RESOURCE + "\n" + + " \n" + + " \n" + + " yarn.resource-types.a-custom-resource" + + ".units\n" + + " k\n" + + " \n" + + " \n" + + " yarn.resource-types.a-custom-resource" + + ".maximum-allocation\n" + + " 10000\n" + + " \n" + + "\n") + .getBytes()); + } else { + return super.getConfigurationInputStream(bootstrapConf, name); + } + } + } + + + @Before + public void setUp() throws IOException { + scheduler = new FairScheduler(); + conf = createConfiguration(); + resourceManager = new MockRM(conf); + + ((AsyncDispatcher) resourceManager.getRMContext().getDispatcher()).start(); + resourceManager.getRMContext().getStateStore().start(); + + // to initialize the master key + resourceManager.getRMContext().getContainerTokenSecretManager() + .rollMasterKey(); + + scheduler.setRMContext(resourceManager.getRMContext()); + } + + @After + public void tearDown() { + if (scheduler != null) { + scheduler.stop(); + scheduler = null; + } + if (resourceManager != null) { + resourceManager.stop(); + resourceManager = null; + } + QueueMetrics.clearQueueMetrics(); + DefaultMetricsSystem.shutdown(); + YarnAuthorizationProvider.destroy(); + } + + private Configuration initResourceTypes() { + Configuration conf = new Configuration(); + conf.set(YarnConfiguration.RM_CONFIGURATION_PROVIDER_CLASS, + TestFairSchedulerWithMultiResourceTypes + .CustomResourceTypesConfigurationProvider.class.getName()); + ResourceUtils.resetResourceTypes(conf); + return conf; + } + + @Test + public void testMaximumAllocationRefresh() throws IOException { + Configuration conf = initResourceTypes(); + conf.setInt(YarnConfiguration.RESOURCE_TYPES + "." + ResourceInformation + .VCORES.getName() + MAXIMUM_ALLOCATION, 4); + conf.setInt(YarnConfiguration.RESOURCE_TYPES + "." + ResourceInformation + .MEMORY_MB.getName() + MAXIMUM_ALLOCATION, 512); + scheduler.init(conf); + scheduler.reinitialize(conf, null); + + Resource maxAllowedAllocation = scheduler.getNodeTracker() + .getMaxAllowedAllocation(); + ResourceInformation customResource = maxAllowedAllocation + .getResourceInformation(A_CUSTOM_RESOURCE); + assertEquals(512, maxAllowedAllocation.getMemorySize()); + assertEquals(4, maxAllowedAllocation.getVirtualCores()); + assertEquals(10000, customResource.getValue()); + + conf = new YarnConfiguration(); + conf.set(YarnConfiguration.RESOURCE_TYPES, A_CUSTOM_RESOURCE); + conf.set(YarnConfiguration.RESOURCE_TYPES + "." + A_CUSTOM_RESOURCE + + UNITS, "k"); + conf.setInt(YarnConfiguration.RESOURCE_TYPES + "." + A_CUSTOM_RESOURCE + + MAXIMUM_ALLOCATION, 20000); + conf.setInt(YarnConfiguration.RESOURCE_TYPES + "." + ResourceInformation + .VCORES.getName() + MAXIMUM_ALLOCATION, 8); + conf.setInt(YarnConfiguration.RESOURCE_TYPES + "." + ResourceInformation + .MEMORY_MB.getName() + MAXIMUM_ALLOCATION, 2048); + scheduler.reinitialize(conf, null); + + maxAllowedAllocation = scheduler.getNodeTracker() + .getMaxAllowedAllocation(); + customResource = maxAllowedAllocation + .getResourceInformation(A_CUSTOM_RESOURCE); + assertEquals(2048, maxAllowedAllocation.getMemorySize()); + assertEquals(8, maxAllowedAllocation.getVirtualCores()); + assertEquals(20000, customResource.getValue()); + } + +}