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/ClusterNodeTracker.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/ClusterNodeTracker.java index 0f72c761e80..18827d26393 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/ClusterNodeTracker.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/ClusterNodeTracker.java @@ -28,6 +28,7 @@ import org.apache.hadoop.yarn.api.records.ResourceInformation; import org.apache.hadoop.yarn.api.records.ResourceRequest; import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; +import org.apache.hadoop.yarn.util.UnitsConversionUtil; import org.apache.hadoop.yarn.util.resource.Resources; import org.apache.hadoop.yarn.util.resource.ResourceUtils; @@ -292,10 +293,18 @@ private void updateMaxResources(SchedulerNode node, boolean add) { reportedMaxAllocation = true; for (int i = 0; i < maxAllocation.length; i++) { - long value = totalResources[i].getValue(); + ResourceInformation totalResourcesRI = totalResources[i]; + long value = totalResourcesRI.getValue(); if (value > maxAllocation[i]) { - maxAllocation[i] = value; + ResourceInformation clusterResourcesRI = + clusterCapacity.getResourceInformation(i); + String fromUnit = totalResourcesRI.getUnits(); + String toUnit = clusterResourcesRI.getUnits(); + long convertedValue = toUnit.equals(fromUnit) + ? value + : UnitsConversionUtil.convert(fromUnit, toUnit, value); + maxAllocation[i] = convertedValue; } } } else { // removed node 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/TestClusterNodeTracker.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestClusterNodeTracker.java index c1703bc52e3..9a17fca88a5 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestClusterNodeTracker.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestClusterNodeTracker.java @@ -17,21 +17,22 @@ */ package org.apache.hadoop.yarn.server.resourcemanager.scheduler; -import java.util.Collections; -import java.util.List; - +import com.google.common.collect.ImmutableMap; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.api.records.ResourceRequest; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.resourcetypes.ResourceTypesTestHelper; import org.apache.hadoop.yarn.server.resourcemanager.MockNodes; import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FSSchedulerNode; import org.apache.hadoop.yarn.util.resource.ResourceUtils; - import org.junit.Before; import org.junit.Test; +import java.util.Collections; +import java.util.List; + import static org.junit.Assert.assertEquals; /** @@ -39,6 +40,7 @@ * loss of generality. */ public class TestClusterNodeTracker { + private static final String CUSTOM_RESOURCE_NAME = "test1"; private ClusterNodeTracker nodeTracker; @Before @@ -55,6 +57,18 @@ private void addEight4x4Nodes() { } } + private void addOneNodeWithCustomResource(String name, String value) { + MockNodes.resetHostIds(); + List rmNodes = + MockNodes.newNodes(1, 1, ResourceTypesTestHelper.newResource(1024, 1, + ImmutableMap.builder() + .put(name, value) + .build())); + for (RMNode rmNode : rmNodes) { + nodeTracker.addNode(new FSSchedulerNode(rmNode, false)); + } + } + @Test public void testGetNodeCount() { addEight4x4Nodes(); @@ -83,13 +97,13 @@ public void testMaxAllowedAllocation() { // Add a third resource Configuration conf = new Configuration(); - conf.set(YarnConfiguration.RESOURCE_TYPES, "test1"); + conf.set(YarnConfiguration.RESOURCE_TYPES, CUSTOM_RESOURCE_NAME); ResourceUtils.resetResourceTypes(conf); setup(); Resource maximum = Resource.newInstance(10240, 10, - Collections.singletonMap("test1", 10L)); + Collections.singletonMap(CUSTOM_RESOURCE_NAME, 10L)); nodeTracker.setConfiguredMaxAllocation(maximum); @@ -100,15 +114,15 @@ public void testMaxAllowedAllocation() { List smallNodes = MockNodes.newNodes(1, 1, Resource.newInstance(1024, 2, - Collections.singletonMap("test1", 4L))); + Collections.singletonMap(CUSTOM_RESOURCE_NAME, 4L))); FSSchedulerNode smallNode = new FSSchedulerNode(smallNodes.get(0), false); List mediumNodes = MockNodes.newNodes(1, 1, Resource.newInstance(4096, 2, - Collections.singletonMap("test1", 2L))); + Collections.singletonMap(CUSTOM_RESOURCE_NAME, 2L))); FSSchedulerNode mediumNode = new FSSchedulerNode(mediumNodes.get(0), false); List largeNodes = MockNodes.newNodes(1, 1, Resource.newInstance(16384, 4, - Collections.singletonMap("test1", 1L))); + Collections.singletonMap(CUSTOM_RESOURCE_NAME, 1L))); FSSchedulerNode largeNode = new FSSchedulerNode(largeNodes.get(0), false); nodeTracker.addNode(mediumNode); @@ -126,7 +140,8 @@ public void testMaxAllowedAllocation() { assertEquals("With two nodes added, the ClusterNodeTracker did not " + "return a the maximum allocation that was the max of their aggregate " + "resources", - Resource.newInstance(4096, 2, Collections.singletonMap("test1", 4L)), + Resource.newInstance(4096, 2, + Collections.singletonMap(CUSTOM_RESOURCE_NAME, 4L)), result); nodeTracker.removeNode(smallNode.getNodeID()); @@ -144,7 +159,8 @@ public void testMaxAllowedAllocation() { assertEquals("With two nodes added, the ClusterNodeTracker did not " + "return a the maximum allocation that was the max of their aggregate " + "resources", - Resource.newInstance(10240, 4, Collections.singletonMap("test1", 2L)), + Resource.newInstance(10240, 4, + Collections.singletonMap(CUSTOM_RESOURCE_NAME, 2L)), result); nodeTracker.removeNode(largeNode.getNodeID()); @@ -171,7 +187,8 @@ public void testMaxAllowedAllocation() { assertEquals("With three nodes added, the ClusterNodeTracker did not " + "return a the maximum allocation that was the max of their aggregate " + "resources", - Resource.newInstance(10240, 4, Collections.singletonMap("test1", 4L)), + Resource.newInstance(10240, 4, + Collections.singletonMap(CUSTOM_RESOURCE_NAME, 4L)), result); nodeTracker.removeNode(smallNode.getNodeID()); @@ -183,4 +200,45 @@ public void testMaxAllowedAllocation() { assertEquals("After removing all nodes, the ClusterNodeTracker did not " + "return the configured maximum allocation", maximum, result); } + + @Test + public void testMaxAllowedAllocationWithDifferentUnits() { + // ensure ResourceManager is loaded, so + // ResourceManager.getClusterTimeStamp gets initialized + nodeTracker.getMaxAllowedAllocation(); + + // Add a third resource + Configuration conf = new Configuration(); + + conf.set(YarnConfiguration.RESOURCE_TYPES, CUSTOM_RESOURCE_NAME); + + ResourceUtils.resetResourceTypes(conf); + setup(); + + //ensure we have a configured max allocation over the reported max + // allocation of the node (multiply by 5) + Resource maximum = ResourceTypesTestHelper.newResource(10240, 10, + ImmutableMap.builder() + .put(CUSTOM_RESOURCE_NAME, + Long.valueOf(50L * 100 * 1000 * 1000).toString()) + .build()); + nodeTracker.setConfiguredMaxAllocation(maximum); + + addOneNodeWithCustomResource(CUSTOM_RESOURCE_NAME, "100M"); + + //assert + Resource maxAllowedAllocation = nodeTracker.getMaxAllowedAllocation(); + Resource clusterCapacity = nodeTracker.getClusterCapacity(); + + //MEGA -> Kilo (*1000), Kilo -> Base (*1000) + assertEquals(1024, clusterCapacity.getMemorySize()); + assertEquals(1, clusterCapacity.getVirtualCores()); + assertEquals(100 * 1000 * 1000, + clusterCapacity.getResourceValue(CUSTOM_RESOURCE_NAME)); + + assertEquals(1024, maxAllowedAllocation.getMemorySize()); + assertEquals(1, maxAllowedAllocation.getVirtualCores()); + assertEquals(100 * 1000 * 1000, maxAllowedAllocation.getResourceValue( + CUSTOM_RESOURCE_NAME)); + } } \ No newline at end of file