YARN-9116. Capacity Scheduler: implements queue level maximum-allocation inheritance. Contributed by Aihua Xu.
This commit is contained in:
parent
c726445990
commit
a4bd64e724
|
@ -20,14 +20,18 @@ package org.apache.hadoop.yarn.util.resource;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.ResourceTypes;
|
import org.apache.hadoop.yarn.api.protocolrecords.ResourceTypes;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceTypeInfo;
|
import org.apache.hadoop.yarn.api.records.ResourceTypeInfo;
|
||||||
|
import org.apache.hadoop.yarn.api.records.impl.LightWeightResource;
|
||||||
import org.apache.hadoop.yarn.conf.ConfigurationProvider;
|
import org.apache.hadoop.yarn.conf.ConfigurationProvider;
|
||||||
import org.apache.hadoop.yarn.conf.ConfigurationProviderFactory;
|
import org.apache.hadoop.yarn.conf.ConfigurationProviderFactory;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
|
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
|
||||||
import org.apache.hadoop.yarn.exceptions.YarnException;
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||||
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
|
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
|
||||||
import org.apache.hadoop.yarn.util.UnitsConversionUtil;
|
import org.apache.hadoop.yarn.util.UnitsConversionUtil;
|
||||||
|
@ -71,6 +75,8 @@ public class ResourceUtils {
|
||||||
"^(((\\p{Alnum}([\\p{Alnum}-]*\\p{Alnum})?\\.)*"
|
"^(((\\p{Alnum}([\\p{Alnum}-]*\\p{Alnum})?\\.)*"
|
||||||
+ "\\p{Alnum}([\\p{Alnum}-]*\\p{Alnum})?)/)?\\p{Alpha}([\\w.-]*)$");
|
+ "\\p{Alnum}([\\p{Alnum}-]*\\p{Alnum})?)/)?\\p{Alpha}([\\w.-]*)$");
|
||||||
|
|
||||||
|
private final static String RES_PATTERN = "^[^=]+=\\d+\\s?\\w*$";
|
||||||
|
|
||||||
private static volatile boolean initializedResources = false;
|
private static volatile boolean initializedResources = false;
|
||||||
private static final Map<String, Integer> RESOURCE_NAME_TO_INDEX =
|
private static final Map<String, Integer> RESOURCE_NAME_TO_INDEX =
|
||||||
new ConcurrentHashMap<String, Integer>();
|
new ConcurrentHashMap<String, Integer>();
|
||||||
|
@ -776,4 +782,108 @@ public class ResourceUtils {
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a new {@link Resource} instance with all resource values
|
||||||
|
* initialized to {@code value}.
|
||||||
|
* @param value the value to use for all resources
|
||||||
|
* @return a new {@link Resource} instance
|
||||||
|
*/
|
||||||
|
@InterfaceAudience.Private
|
||||||
|
@InterfaceStability.Unstable
|
||||||
|
public static Resource createResourceWithSameValue(long value) {
|
||||||
|
LightWeightResource res = new LightWeightResource(value,
|
||||||
|
Long.valueOf(value).intValue());
|
||||||
|
int numberOfResources = getNumberOfKnownResourceTypes();
|
||||||
|
for (int i = 2; i < numberOfResources; i++) {
|
||||||
|
res.setResourceValue(i, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@InterfaceAudience.Private
|
||||||
|
@InterfaceStability.Unstable
|
||||||
|
public static Resource createResourceFromString(
|
||||||
|
String resourceStr,
|
||||||
|
List<ResourceTypeInfo> resourceTypeInfos) {
|
||||||
|
Map<String, Long> typeToValue = parseResourcesString(resourceStr);
|
||||||
|
validateResourceTypes(typeToValue.keySet(), resourceTypeInfos);
|
||||||
|
Resource resource = Resource.newInstance(0, 0);
|
||||||
|
for (Entry<String, Long> entry : typeToValue.entrySet()) {
|
||||||
|
resource.setResourceValue(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Long> parseResourcesString(String resourcesStr) {
|
||||||
|
Map<String, Long> resources = new HashMap<>();
|
||||||
|
String[] pairs = resourcesStr.trim().split(",");
|
||||||
|
for (String resource : pairs) {
|
||||||
|
resource = resource.trim();
|
||||||
|
if (!resource.matches(RES_PATTERN)) {
|
||||||
|
throw new IllegalArgumentException("\"" + resource + "\" is not a "
|
||||||
|
+ "valid resource type/amount pair. "
|
||||||
|
+ "Please provide key=amount pairs separated by commas.");
|
||||||
|
}
|
||||||
|
String[] splits = resource.split("=");
|
||||||
|
String key = splits[0], value = splits[1];
|
||||||
|
String units = getUnits(value);
|
||||||
|
|
||||||
|
String valueWithoutUnit = value.substring(0,
|
||||||
|
value.length()- units.length()).trim();
|
||||||
|
long resourceValue = Long.parseLong(valueWithoutUnit);
|
||||||
|
|
||||||
|
// Convert commandline unit to standard YARN unit.
|
||||||
|
if (units.equals("M") || units.equals("m")) {
|
||||||
|
units = "Mi";
|
||||||
|
} else if (units.equals("G") || units.equals("g")) {
|
||||||
|
units = "Gi";
|
||||||
|
} else if (units.isEmpty()) {
|
||||||
|
// do nothing;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Acceptable units are M/G or empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
// special handle memory-mb and memory
|
||||||
|
if (key.equals(ResourceInformation.MEMORY_URI)) {
|
||||||
|
if (!units.isEmpty()) {
|
||||||
|
resourceValue = UnitsConversionUtil.convert(units, "Mi",
|
||||||
|
resourceValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.equals("memory")) {
|
||||||
|
key = ResourceInformation.MEMORY_URI;
|
||||||
|
resourceValue = UnitsConversionUtil.convert(units, "Mi",
|
||||||
|
resourceValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// special handle gpu
|
||||||
|
if (key.equals("gpu")) {
|
||||||
|
key = ResourceInformation.GPU_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// special handle fpga
|
||||||
|
if (key.equals("fpga")) {
|
||||||
|
key = ResourceInformation.FPGA_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
resources.put(key, resourceValue);
|
||||||
|
}
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void validateResourceTypes(
|
||||||
|
Iterable<String> resourceNames,
|
||||||
|
List<ResourceTypeInfo> resourceTypeInfos)
|
||||||
|
throws ResourceNotFoundException {
|
||||||
|
for (String resourceName : resourceNames) {
|
||||||
|
if (!resourceTypeInfos.stream().anyMatch(
|
||||||
|
e -> e.getName().equals(resourceName))) {
|
||||||
|
throw new ResourceNotFoundException(
|
||||||
|
"Unknown resource: " + resourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,23 +16,15 @@ package org.apache.hadoop.yarn.submarine.client.cli;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceTypeInfo;
|
|
||||||
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
|
|
||||||
import org.apache.hadoop.yarn.exceptions.YarnException;
|
|
||||||
import org.apache.hadoop.yarn.submarine.client.cli.param.RunJobParameters;
|
import org.apache.hadoop.yarn.submarine.client.cli.param.RunJobParameters;
|
||||||
import org.apache.hadoop.yarn.submarine.common.exception.SubmarineRuntimeException;
|
import org.apache.hadoop.yarn.submarine.common.exception.SubmarineRuntimeException;
|
||||||
import org.apache.hadoop.yarn.submarine.common.fs.RemoteDirectoryManager;
|
import org.apache.hadoop.yarn.submarine.common.fs.RemoteDirectoryManager;
|
||||||
import org.apache.hadoop.yarn.util.UnitsConversionUtil;
|
|
||||||
import org.apache.hadoop.yarn.util.resource.ResourceUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.apache.hadoop.yarn.submarine.client.cli.CliConstants.KEYTAB;
|
import static org.apache.hadoop.yarn.submarine.client.cli.CliConstants.KEYTAB;
|
||||||
|
@ -41,7 +33,6 @@ import static org.apache.hadoop.yarn.submarine.client.cli.CliConstants.PRINCIPAL
|
||||||
public class CliUtils {
|
public class CliUtils {
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
LoggerFactory.getLogger(CliUtils.class);
|
LoggerFactory.getLogger(CliUtils.class);
|
||||||
private final static String RES_PATTERN = "^[^=]+=\\d+\\s?\\w*$";
|
|
||||||
/**
|
/**
|
||||||
* Replace patterns inside cli
|
* Replace patterns inside cli
|
||||||
*
|
*
|
||||||
|
@ -74,86 +65,6 @@ public class CliUtils {
|
||||||
return newCli;
|
return newCli;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Long> parseResourcesString(String resourcesStr) {
|
|
||||||
Map<String, Long> resources = new HashMap<>();
|
|
||||||
String[] pairs = resourcesStr.trim().split(",");
|
|
||||||
for (String resource : pairs) {
|
|
||||||
resource = resource.trim();
|
|
||||||
if (!resource.matches(RES_PATTERN)) {
|
|
||||||
throw new IllegalArgumentException("\"" + resource + "\" is not a "
|
|
||||||
+ "valid resource type/amount pair. "
|
|
||||||
+ "Please provide key=amount pairs separated by commas.");
|
|
||||||
}
|
|
||||||
String[] splits = resource.split("=");
|
|
||||||
String key = splits[0], value = splits[1];
|
|
||||||
String units = ResourceUtils.getUnits(value);
|
|
||||||
|
|
||||||
String valueWithoutUnit = value.substring(0,
|
|
||||||
value.length()- units.length()).trim();
|
|
||||||
long resourceValue = Long.parseLong(valueWithoutUnit);
|
|
||||||
|
|
||||||
// Convert commandline unit to standard YARN unit.
|
|
||||||
if (units.equals("M") || units.equals("m")) {
|
|
||||||
units = "Mi";
|
|
||||||
} else if (units.equals("G") || units.equals("g")) {
|
|
||||||
units = "Gi";
|
|
||||||
} else if (units.isEmpty()) {
|
|
||||||
// do nothing;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Acceptable units are M/G or empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
// special handle memory-mb and memory
|
|
||||||
if (key.equals(ResourceInformation.MEMORY_URI)) {
|
|
||||||
if (!units.isEmpty()) {
|
|
||||||
resourceValue = UnitsConversionUtil.convert(units, "Mi",
|
|
||||||
resourceValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key.equals("memory")) {
|
|
||||||
key = ResourceInformation.MEMORY_URI;
|
|
||||||
resourceValue = UnitsConversionUtil.convert(units, "Mi",
|
|
||||||
resourceValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// special handle gpu
|
|
||||||
if (key.equals("gpu")) {
|
|
||||||
key = ResourceInformation.GPU_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// special handle fpga
|
|
||||||
if (key.equals("fpga")) {
|
|
||||||
key = ResourceInformation.FPGA_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
resources.put(key, resourceValue);
|
|
||||||
}
|
|
||||||
return resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void validateResourceTypes(Iterable<String> resourceNames,
|
|
||||||
List<ResourceTypeInfo> resourceTypes) throws IOException, YarnException {
|
|
||||||
for (String resourceName : resourceNames) {
|
|
||||||
if (!resourceTypes.stream().anyMatch(
|
|
||||||
e -> e.getName().equals(resourceName))) {
|
|
||||||
throw new ResourceNotFoundException(
|
|
||||||
"Unknown resource: " + resourceName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Resource createResourceFromString(String resourceStr,
|
|
||||||
List<ResourceTypeInfo> resourceTypes) throws IOException, YarnException {
|
|
||||||
Map<String, Long> typeToValue = parseResourcesString(resourceStr);
|
|
||||||
validateResourceTypes(typeToValue.keySet(), resourceTypes);
|
|
||||||
Resource resource = Resource.newInstance(0, 0);
|
|
||||||
for (Map.Entry<String, Long> entry : typeToValue.entrySet()) {
|
|
||||||
resource.setResourceValue(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is it for help?
|
// Is it for help?
|
||||||
public static boolean argsForHelp(String[] args) {
|
public static boolean argsForHelp(String[] args) {
|
||||||
if (args == null || args.length == 0)
|
if (args == null || args.length == 0)
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||||
import org.apache.hadoop.yarn.submarine.client.cli.CliConstants;
|
import org.apache.hadoop.yarn.submarine.client.cli.CliConstants;
|
||||||
import org.apache.hadoop.yarn.submarine.client.cli.CliUtils;
|
import org.apache.hadoop.yarn.submarine.client.cli.CliUtils;
|
||||||
import org.apache.hadoop.yarn.submarine.common.ClientContext;
|
import org.apache.hadoop.yarn.submarine.common.ClientContext;
|
||||||
|
import org.apache.hadoop.yarn.util.resource.ResourceUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -104,7 +105,7 @@ public class RunJobParameters extends RunParameters {
|
||||||
throw new ParseException(
|
throw new ParseException(
|
||||||
"--" + CliConstants.WORKER_RES + " is absent.");
|
"--" + CliConstants.WORKER_RES + " is absent.");
|
||||||
}
|
}
|
||||||
workerResource = CliUtils.createResourceFromString(
|
workerResource = ResourceUtils.createResourceFromString(
|
||||||
workerResourceStr,
|
workerResourceStr,
|
||||||
clientContext.getOrCreateYarnClient().getResourceTypeInfo());
|
clientContext.getOrCreateYarnClient().getResourceTypeInfo());
|
||||||
}
|
}
|
||||||
|
@ -115,7 +116,7 @@ public class RunJobParameters extends RunParameters {
|
||||||
if (psResourceStr == null) {
|
if (psResourceStr == null) {
|
||||||
throw new ParseException("--" + CliConstants.PS_RES + " is absent.");
|
throw new ParseException("--" + CliConstants.PS_RES + " is absent.");
|
||||||
}
|
}
|
||||||
psResource = CliUtils.createResourceFromString(psResourceStr,
|
psResource = ResourceUtils.createResourceFromString(psResourceStr,
|
||||||
clientContext.getOrCreateYarnClient().getResourceTypeInfo());
|
clientContext.getOrCreateYarnClient().getResourceTypeInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ public class RunJobParameters extends RunParameters {
|
||||||
if (tensorboardResourceStr == null || tensorboardResourceStr.isEmpty()) {
|
if (tensorboardResourceStr == null || tensorboardResourceStr.isEmpty()) {
|
||||||
tensorboardResourceStr = CliConstants.TENSORBOARD_DEFAULT_RESOURCES;
|
tensorboardResourceStr = CliConstants.TENSORBOARD_DEFAULT_RESOURCES;
|
||||||
}
|
}
|
||||||
tensorboardResource = CliUtils.createResourceFromString(
|
tensorboardResource = ResourceUtils.createResourceFromString(
|
||||||
tensorboardResourceStr,
|
tensorboardResourceStr,
|
||||||
clientContext.getOrCreateYarnClient().getResourceTypeInfo());
|
clientContext.getOrCreateYarnClient().getResourceTypeInfo());
|
||||||
tensorboardDockerImage = parsedCommandLine.getOptionValue(
|
tensorboardDockerImage = parsedCommandLine.getOptionValue(
|
||||||
|
|
|
@ -21,9 +21,6 @@ package org.apache.hadoop.yarn.submarine.client.cli;
|
||||||
|
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceTypeInfo;
|
|
||||||
import org.apache.hadoop.yarn.exceptions.YarnException;
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||||
import org.apache.hadoop.yarn.submarine.client.cli.param.RunJobParameters;
|
import org.apache.hadoop.yarn.submarine.client.cli.param.RunJobParameters;
|
||||||
import org.apache.hadoop.yarn.submarine.common.MockClientContext;
|
import org.apache.hadoop.yarn.submarine.common.MockClientContext;
|
||||||
|
@ -32,15 +29,12 @@ import org.apache.hadoop.yarn.submarine.runtimes.RuntimeFactory;
|
||||||
import org.apache.hadoop.yarn.submarine.runtimes.common.JobMonitor;
|
import org.apache.hadoop.yarn.submarine.runtimes.common.JobMonitor;
|
||||||
import org.apache.hadoop.yarn.submarine.runtimes.common.JobSubmitter;
|
import org.apache.hadoop.yarn.submarine.runtimes.common.JobSubmitter;
|
||||||
import org.apache.hadoop.yarn.submarine.runtimes.common.SubmarineStorage;
|
import org.apache.hadoop.yarn.submarine.runtimes.common.SubmarineStorage;
|
||||||
import org.apache.hadoop.yarn.util.resource.ResourceUtils;
|
|
||||||
import org.apache.hadoop.yarn.util.resource.Resources;
|
import org.apache.hadoop.yarn.util.resource.Resources;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
@ -204,72 +198,4 @@ public class TestRunJobCliParsing {
|
||||||
"python run-ps.py --input=hdfs://input --model_dir=hdfs://output/model",
|
"python run-ps.py --input=hdfs://input --model_dir=hdfs://output/model",
|
||||||
runJobCli.getRunJobParameters().getPSLaunchCmd());
|
runJobCli.getRunJobParameters().getPSLaunchCmd());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testResourceUnitParsing() throws Exception {
|
|
||||||
Resource res = CliUtils.createResourceFromString("memory=20g,vcores=3",
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
Assert.assertEquals(Resources.createResource(20 * 1024, 3), res);
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory=20G,vcores=3",
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
Assert.assertEquals(Resources.createResource(20 * 1024, 3), res);
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory=20M,vcores=3",
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
Assert.assertEquals(Resources.createResource(20, 3), res);
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory=20m,vcores=3",
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
Assert.assertEquals(Resources.createResource(20, 3), res);
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory-mb=20,vcores=3",
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
Assert.assertEquals(Resources.createResource(20, 3), res);
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory-mb=20m,vcores=3",
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
Assert.assertEquals(Resources.createResource(20, 3), res);
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory-mb=20G,vcores=3",
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
Assert.assertEquals(Resources.createResource(20 * 1024, 3), res);
|
|
||||||
|
|
||||||
// W/o unit for memory means bits, and 20 bits will be rounded to 0
|
|
||||||
res = CliUtils.createResourceFromString("memory=20,vcores=3",
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
Assert.assertEquals(Resources.createResource(0, 3), res);
|
|
||||||
|
|
||||||
// Test multiple resources
|
|
||||||
List<ResourceTypeInfo> resTypes = new ArrayList<>(
|
|
||||||
ResourceUtils.getResourcesTypeInfo());
|
|
||||||
resTypes.add(ResourceTypeInfo.newInstance(ResourceInformation.GPU_URI, ""));
|
|
||||||
ResourceUtils.reinitializeResources(resTypes);
|
|
||||||
res = CliUtils.createResourceFromString("memory=2G,vcores=3,gpu=0",
|
|
||||||
resTypes);
|
|
||||||
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
|
||||||
Assert.assertEquals(0, res.getResourceValue(ResourceInformation.GPU_URI));
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory=2G,vcores=3,gpu=3",
|
|
||||||
resTypes);
|
|
||||||
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
|
||||||
Assert.assertEquals(3, res.getResourceValue(ResourceInformation.GPU_URI));
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory=2G,vcores=3",
|
|
||||||
resTypes);
|
|
||||||
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
|
||||||
Assert.assertEquals(0, res.getResourceValue(ResourceInformation.GPU_URI));
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory=2G,vcores=3,yarn.io/gpu=0",
|
|
||||||
resTypes);
|
|
||||||
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
|
||||||
Assert.assertEquals(0, res.getResourceValue(ResourceInformation.GPU_URI));
|
|
||||||
|
|
||||||
res = CliUtils.createResourceFromString("memory=2G,vcores=3,yarn.io/gpu=3",
|
|
||||||
resTypes);
|
|
||||||
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
|
||||||
Assert.assertEquals(3, res.getResourceValue(ResourceInformation.GPU_URI));
|
|
||||||
|
|
||||||
// TODO, add more negative tests.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.apache.hadoop.classification.InterfaceAudience.Private;
|
||||||
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
||||||
import org.apache.hadoop.yarn.api.records.impl.LightWeightResource;
|
|
||||||
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
|
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,25 +38,6 @@ public class Resources {
|
||||||
private static final Log LOG =
|
private static final Log LOG =
|
||||||
LogFactory.getLog(Resources.class);
|
LogFactory.getLog(Resources.class);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a new {@link Resource} instance with all resource values
|
|
||||||
* initialized to {@code value}.
|
|
||||||
* @param value the value to use for all resources
|
|
||||||
* @return a new {@link Resource} instance
|
|
||||||
*/
|
|
||||||
@Private
|
|
||||||
@Unstable
|
|
||||||
public static Resource createResourceWithSameValue(long value) {
|
|
||||||
LightWeightResource res = new LightWeightResource(value,
|
|
||||||
Long.valueOf(value).intValue());
|
|
||||||
int numberOfResources = ResourceUtils.getNumberOfKnownResourceTypes();
|
|
||||||
for (int i = 2; i < numberOfResources; i++) {
|
|
||||||
res.setResourceValue(i, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to create a resource with a fixed value for all resource
|
* Helper class to create a resource with a fixed value for all resource
|
||||||
* types. For example, a NONE resource which returns 0 for any resource type.
|
* types. For example, a NONE resource which returns 0 for any resource type.
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.ResourceTypes;
|
import org.apache.hadoop.yarn.api.protocolrecords.ResourceTypes;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
||||||
|
import org.apache.hadoop.yarn.api.records.ResourceTypeInfo;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
|
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@ -31,7 +32,9 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -391,6 +394,74 @@ public class TestResourceUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResourceUnitParsing() throws Exception {
|
||||||
|
Resource res = ResourceUtils.createResourceFromString("memory=20g,vcores=3",
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
Assert.assertEquals(Resources.createResource(20 * 1024, 3), res);
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString("memory=20G,vcores=3",
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
Assert.assertEquals(Resources.createResource(20 * 1024, 3), res);
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString("memory=20M,vcores=3",
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
Assert.assertEquals(Resources.createResource(20, 3), res);
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString("memory=20m,vcores=3",
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
Assert.assertEquals(Resources.createResource(20, 3), res);
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString("memory-mb=20,vcores=3",
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
Assert.assertEquals(Resources.createResource(20, 3), res);
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString("memory-mb=20m,vcores=3",
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
Assert.assertEquals(Resources.createResource(20, 3), res);
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString("memory-mb=20G,vcores=3",
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
Assert.assertEquals(Resources.createResource(20 * 1024, 3), res);
|
||||||
|
|
||||||
|
// W/o unit for memory means bits, and 20 bits will be rounded to 0
|
||||||
|
res = ResourceUtils.createResourceFromString("memory=20,vcores=3",
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
Assert.assertEquals(Resources.createResource(0, 3), res);
|
||||||
|
|
||||||
|
// Test multiple resources
|
||||||
|
List<ResourceTypeInfo> resTypes = new ArrayList<>(
|
||||||
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
|
resTypes.add(ResourceTypeInfo.newInstance(ResourceInformation.GPU_URI, ""));
|
||||||
|
ResourceUtils.reinitializeResources(resTypes);
|
||||||
|
res = ResourceUtils.createResourceFromString("memory=2G,vcores=3,gpu=0",
|
||||||
|
resTypes);
|
||||||
|
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
||||||
|
Assert.assertEquals(0, res.getResourceValue(ResourceInformation.GPU_URI));
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString("memory=2G,vcores=3,gpu=3",
|
||||||
|
resTypes);
|
||||||
|
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
||||||
|
Assert.assertEquals(3, res.getResourceValue(ResourceInformation.GPU_URI));
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString("memory=2G,vcores=3",
|
||||||
|
resTypes);
|
||||||
|
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
||||||
|
Assert.assertEquals(0, res.getResourceValue(ResourceInformation.GPU_URI));
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString(
|
||||||
|
"memory=2G,vcores=3,yarn.io/gpu=0", resTypes);
|
||||||
|
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
||||||
|
Assert.assertEquals(0, res.getResourceValue(ResourceInformation.GPU_URI));
|
||||||
|
|
||||||
|
res = ResourceUtils.createResourceFromString(
|
||||||
|
"memory=2G,vcores=3,yarn.io/gpu=3", resTypes);
|
||||||
|
Assert.assertEquals(2 * 1024, res.getMemorySize());
|
||||||
|
Assert.assertEquals(3, res.getResourceValue(ResourceInformation.GPU_URI));
|
||||||
|
|
||||||
|
// TODO, add more negative tests.
|
||||||
|
}
|
||||||
|
|
||||||
public static String setupResourceTypes(Configuration conf, String filename)
|
public static String setupResourceTypes(Configuration conf, String filename)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
File source = new File(
|
File source = new File(
|
||||||
|
|
|
@ -269,7 +269,7 @@ public class TestResources {
|
||||||
unsetExtraResourceType();
|
unsetExtraResourceType();
|
||||||
setupExtraResourceType();
|
setupExtraResourceType();
|
||||||
|
|
||||||
Resource res = Resources.createResourceWithSameValue(11L);
|
Resource res = ResourceUtils.createResourceWithSameValue(11L);
|
||||||
assertEquals(11L, res.getMemorySize());
|
assertEquals(11L, res.getMemorySize());
|
||||||
assertEquals(11, res.getVirtualCores());
|
assertEquals(11, res.getVirtualCores());
|
||||||
assertEquals(11L, res.getResourceInformation(EXTRA_RESOURCE_TYPE).getValue());
|
assertEquals(11L, res.getResourceInformation(EXTRA_RESOURCE_TYPE).getValue());
|
||||||
|
@ -280,7 +280,7 @@ public class TestResources {
|
||||||
unsetExtraResourceType();
|
unsetExtraResourceType();
|
||||||
setupExtraResourceType();
|
setupExtraResourceType();
|
||||||
|
|
||||||
Resource res = Resources.createResourceWithSameValue(11);
|
Resource res = ResourceUtils.createResourceWithSameValue(11);
|
||||||
assertEquals(11, res.getMemorySize());
|
assertEquals(11, res.getMemorySize());
|
||||||
assertEquals(11, res.getVirtualCores());
|
assertEquals(11, res.getVirtualCores());
|
||||||
assertEquals(11, res.getResourceInformation(EXTRA_RESOURCE_TYPE).getValue());
|
assertEquals(11, res.getResourceInformation(EXTRA_RESOURCE_TYPE).getValue());
|
||||||
|
@ -288,14 +288,14 @@ public class TestResources {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateSimpleResourceWithSameLongValue() {
|
public void testCreateSimpleResourceWithSameLongValue() {
|
||||||
Resource res = Resources.createResourceWithSameValue(11L);
|
Resource res = ResourceUtils.createResourceWithSameValue(11L);
|
||||||
assertEquals(11L, res.getMemorySize());
|
assertEquals(11L, res.getMemorySize());
|
||||||
assertEquals(11, res.getVirtualCores());
|
assertEquals(11, res.getVirtualCores());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateSimpleResourceWithSameIntValue() {
|
public void testCreateSimpleResourceWithSameIntValue() {
|
||||||
Resource res = Resources.createResourceWithSameValue(11);
|
Resource res = ResourceUtils.createResourceWithSameValue(11);
|
||||||
assertEquals(11, res.getMemorySize());
|
assertEquals(11, res.getMemorySize());
|
||||||
assertEquals(11, res.getVirtualCores());
|
assertEquals(11, res.getVirtualCores());
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import org.apache.hadoop.yarn.api.records.QueueInfo;
|
||||||
import org.apache.hadoop.yarn.api.records.QueueState;
|
import org.apache.hadoop.yarn.api.records.QueueState;
|
||||||
import org.apache.hadoop.yarn.api.records.QueueStatistics;
|
import org.apache.hadoop.yarn.api.records.QueueStatistics;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
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.conf.YarnConfiguration;
|
||||||
import org.apache.hadoop.yarn.exceptions.YarnException;
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||||
import org.apache.hadoop.yarn.factories.RecordFactory;
|
import org.apache.hadoop.yarn.factories.RecordFactory;
|
||||||
|
@ -69,10 +70,13 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaS
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaSchedulerNode;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaSchedulerNode;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.placement.SimpleCandidateNodeSet;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.placement.SimpleCandidateNodeSet;
|
||||||
import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
|
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 org.apache.hadoop.yarn.util.resource.Resources;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.UNDEFINED;
|
||||||
|
|
||||||
public abstract class AbstractCSQueue implements CSQueue {
|
public abstract class AbstractCSQueue implements CSQueue {
|
||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(AbstractCSQueue.class);
|
private static final Log LOG = LogFactory.getLog(AbstractCSQueue.class);
|
||||||
|
@ -361,9 +365,9 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
capacityConfigType = CapacityConfigType.NONE;
|
capacityConfigType = CapacityConfigType.NONE;
|
||||||
updateConfigurableResourceRequirement(getQueuePath(), clusterResource);
|
updateConfigurableResourceRequirement(getQueuePath(), clusterResource);
|
||||||
|
|
||||||
this.maximumAllocation =
|
// Setup queue's maximumAllocation respecting the global setting
|
||||||
configuration.getMaximumAllocationPerQueue(
|
// and queue setting
|
||||||
getQueuePath());
|
setupMaximumAllocation(configuration);
|
||||||
|
|
||||||
// initialized the queue state based on previous state, configured state
|
// initialized the queue state based on previous state, configured state
|
||||||
// and its parent state.
|
// and its parent state.
|
||||||
|
@ -425,6 +429,51 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupMaximumAllocation(CapacitySchedulerConfiguration csConf) {
|
||||||
|
String queue = getQueuePath();
|
||||||
|
Resource clusterMax = ResourceUtils
|
||||||
|
.fetchMaximumAllocationFromConfig(csConf);
|
||||||
|
Resource queueMax = csConf.getQueueMaximumAllocation(queue);
|
||||||
|
|
||||||
|
maximumAllocation = Resources.clone(
|
||||||
|
parent == null ? clusterMax : parent.getMaximumAllocation());
|
||||||
|
|
||||||
|
String errMsg =
|
||||||
|
"Queue maximum allocation cannot be larger than the cluster setting"
|
||||||
|
+ " for queue " + queue
|
||||||
|
+ " max allocation per queue: %s"
|
||||||
|
+ " cluster setting: " + clusterMax;
|
||||||
|
|
||||||
|
if (queueMax == Resources.none()) {
|
||||||
|
// Handle backward compatibility
|
||||||
|
long queueMemory = csConf.getQueueMaximumAllocationMb(queue);
|
||||||
|
int queueVcores = csConf.getQueueMaximumAllocationVcores(queue);
|
||||||
|
if (queueMemory != UNDEFINED) {
|
||||||
|
maximumAllocation.setMemorySize(queueMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queueVcores != UNDEFINED) {
|
||||||
|
maximumAllocation.setVirtualCores(queueVcores);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((queueMemory != UNDEFINED && queueMemory > clusterMax.getMemorySize()
|
||||||
|
|| (queueVcores != UNDEFINED
|
||||||
|
&& queueVcores > clusterMax.getVirtualCores()))) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format(errMsg, maximumAllocation));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Queue level maximum-allocation can't be larger than cluster setting
|
||||||
|
for (ResourceInformation ri : queueMax.getResources()) {
|
||||||
|
if (ri.compareTo(clusterMax.getResourceInformation(ri.getName())) > 0) {
|
||||||
|
throw new IllegalArgumentException(String.format(errMsg, queueMax));
|
||||||
|
}
|
||||||
|
|
||||||
|
maximumAllocation.setResourceInformation(ri.getName(), ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Float> getUserWeightsFromHierarchy
|
private Map<String, Float> getUserWeightsFromHierarchy
|
||||||
(CapacitySchedulerConfiguration configuration) throws
|
(CapacitySchedulerConfiguration configuration) throws
|
||||||
IOException {
|
IOException {
|
||||||
|
|
|
@ -86,6 +86,10 @@ public interface CSQueue extends SchedulerQueue<CSQueue> {
|
||||||
|
|
||||||
public PrivilegedEntity getPrivilegedEntity();
|
public PrivilegedEntity getPrivilegedEntity();
|
||||||
|
|
||||||
|
Resource getMaximumAllocation();
|
||||||
|
|
||||||
|
Resource getMinimumAllocation();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the configured <em>capacity</em> of the queue.
|
* Get the configured <em>capacity</em> of the queue.
|
||||||
* @return configured queue capacity
|
* @return configured queue capacity
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -140,13 +141,15 @@ public class CapacitySchedulerConfiguration extends ReservationSchedulerConfigur
|
||||||
@Private
|
@Private
|
||||||
public static final boolean DEFAULT_RESERVE_CONT_LOOK_ALL_NODES = true;
|
public static final boolean DEFAULT_RESERVE_CONT_LOOK_ALL_NODES = true;
|
||||||
|
|
||||||
|
@Private
|
||||||
|
public static final String MAXIMUM_ALLOCATION = "maximum-allocation";
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
public static final String MAXIMUM_ALLOCATION_MB = "maximum-allocation-mb";
|
public static final String MAXIMUM_ALLOCATION_MB = "maximum-allocation-mb";
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
public static final String MAXIMUM_ALLOCATION_VCORES =
|
public static final String MAXIMUM_ALLOCATION_VCORES =
|
||||||
"maximum-allocation-vcores";
|
"maximum-allocation-vcores";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ordering policy of queues
|
* Ordering policy of queues
|
||||||
*/
|
*/
|
||||||
|
@ -889,50 +892,32 @@ public class CapacitySchedulerConfiguration extends ReservationSchedulerConfigur
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the per queue setting for the maximum limit to allocate to
|
* Get maximum_allocation setting for the specified queue from the
|
||||||
* each container request.
|
* configuration.
|
||||||
*
|
*
|
||||||
* @param queue
|
* @param queue
|
||||||
* name of the queue
|
* name of the queue
|
||||||
* @return setting specified per queue else falls back to the cluster setting
|
* @return Resource object or Resource.none if not set
|
||||||
*/
|
*/
|
||||||
public Resource getMaximumAllocationPerQueue(String queue) {
|
public Resource getQueueMaximumAllocation(String queue) {
|
||||||
// Only support to specify memory and vcores maximum allocation per queue
|
|
||||||
// for now.
|
|
||||||
String queuePrefix = getQueuePrefix(queue);
|
String queuePrefix = getQueuePrefix(queue);
|
||||||
long maxAllocationMbPerQueue = getInt(queuePrefix + MAXIMUM_ALLOCATION_MB,
|
String rawQueueMaxAllocation = get(queuePrefix + MAXIMUM_ALLOCATION, null);
|
||||||
(int)UNDEFINED);
|
if (Strings.isNullOrEmpty(rawQueueMaxAllocation)) {
|
||||||
int maxAllocationVcoresPerQueue = getInt(
|
return Resources.none();
|
||||||
queuePrefix + MAXIMUM_ALLOCATION_VCORES, (int)UNDEFINED);
|
} else {
|
||||||
if (LOG.isDebugEnabled()) {
|
return ResourceUtils.createResourceFromString(rawQueueMaxAllocation,
|
||||||
LOG.debug("max alloc mb per queue for " + queue + " is "
|
ResourceUtils.getResourcesTypeInfo());
|
||||||
+ maxAllocationMbPerQueue);
|
|
||||||
LOG.debug("max alloc vcores per queue for " + queue + " is "
|
|
||||||
+ maxAllocationVcoresPerQueue);
|
|
||||||
}
|
}
|
||||||
Resource clusterMax = ResourceUtils.fetchMaximumAllocationFromConfig(this);
|
}
|
||||||
if (maxAllocationMbPerQueue == (int)UNDEFINED) {
|
|
||||||
LOG.info("max alloc mb per queue for " + queue + " is undefined");
|
public long getQueueMaximumAllocationMb(String queue) {
|
||||||
maxAllocationMbPerQueue = clusterMax.getMemorySize();
|
String queuePrefix = getQueuePrefix(queue);
|
||||||
}
|
return getInt(queuePrefix + MAXIMUM_ALLOCATION_MB, (int)UNDEFINED);
|
||||||
if (maxAllocationVcoresPerQueue == (int)UNDEFINED) {
|
}
|
||||||
LOG.info("max alloc vcore per queue for " + queue + " is undefined");
|
|
||||||
maxAllocationVcoresPerQueue = clusterMax.getVirtualCores();
|
public int getQueueMaximumAllocationVcores(String queue) {
|
||||||
}
|
String queuePrefix = getQueuePrefix(queue);
|
||||||
// Copy from clusterMax and overwrite per-queue's maximum memory/vcore
|
return getInt(queuePrefix + MAXIMUM_ALLOCATION_VCORES, (int)UNDEFINED);
|
||||||
// allocation.
|
|
||||||
Resource result = Resources.clone(clusterMax);
|
|
||||||
result.setMemorySize(maxAllocationMbPerQueue);
|
|
||||||
result.setVirtualCores(maxAllocationVcoresPerQueue);
|
|
||||||
if (maxAllocationMbPerQueue > clusterMax.getMemorySize()
|
|
||||||
|| maxAllocationVcoresPerQueue > clusterMax.getVirtualCores()) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Queue maximum allocation cannot be larger than the cluster setting"
|
|
||||||
+ " for queue " + queue
|
|
||||||
+ " max allocation per queue: " + result
|
|
||||||
+ " cluster setting: " + clusterMax);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getEnableUserMetrics() {
|
public boolean getEnableUserMetrics() {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
import org.apache.hadoop.yarn.api.records.ResourceInformation;
|
||||||
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
|
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
|
||||||
import org.apache.hadoop.yarn.util.resource.ResourceUtils;
|
import org.apache.hadoop.yarn.util.resource.ResourceUtils;
|
||||||
import org.apache.hadoop.yarn.util.resource.Resources;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code ConfigurableResource} object represents an entity that is used to
|
* A {@code ConfigurableResource} object represents an entity that is used to
|
||||||
|
@ -53,7 +52,7 @@ public class ConfigurableResource {
|
||||||
* @param value the value to use for all resources
|
* @param value the value to use for all resources
|
||||||
*/
|
*/
|
||||||
ConfigurableResource(long value) {
|
ConfigurableResource(long value) {
|
||||||
this(Resources.createResourceWithSameValue(value));
|
this(ResourceUtils.createResourceWithSameValue(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurableResource(Resource resource) {
|
public ConfigurableResource(Resource resource) {
|
||||||
|
|
|
@ -18,8 +18,10 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.MAXIMUM_ALLOCATION;
|
||||||
import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.MAXIMUM_ALLOCATION_MB;
|
import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.MAXIMUM_ALLOCATION_MB;
|
||||||
import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.MAXIMUM_ALLOCATION_VCORES;
|
import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.MAXIMUM_ALLOCATION_VCORES;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
@ -2996,8 +2998,8 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
cs.getMaximumResourceCapability().getMemorySize());
|
cs.getMaximumResourceCapability().getMemorySize());
|
||||||
assertEquals("max allocation for A1",
|
assertEquals("max allocation for A1",
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
Resources.none(),
|
||||||
conf.getMaximumAllocationPerQueue(A1).getMemorySize());
|
conf.getQueueMaximumAllocation(A1));
|
||||||
assertEquals("max allocation",
|
assertEquals("max allocation",
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getMemorySize());
|
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getMemorySize());
|
||||||
|
@ -3087,6 +3089,10 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
cs.reinitialize(conf, mockContext);
|
cs.reinitialize(conf, mockContext);
|
||||||
checkQueueCapacities(cs, A_CAPACITY, B_CAPACITY);
|
checkQueueCapacities(cs, A_CAPACITY, B_CAPACITY);
|
||||||
|
|
||||||
|
CSQueue rootQueue = cs.getRootQueue();
|
||||||
|
CSQueue queueA = findQueue(rootQueue, A);
|
||||||
|
CSQueue queueA1 = findQueue(queueA, A1);
|
||||||
|
|
||||||
assertEquals("max capability MB in CS",
|
assertEquals("max capability MB in CS",
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
cs.getMaximumResourceCapability().getMemorySize());
|
cs.getMaximumResourceCapability().getMemorySize());
|
||||||
|
@ -3095,10 +3101,10 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
cs.getMaximumResourceCapability().getVirtualCores());
|
cs.getMaximumResourceCapability().getVirtualCores());
|
||||||
assertEquals("max allocation MB A1",
|
assertEquals("max allocation MB A1",
|
||||||
4096,
|
4096,
|
||||||
conf.getMaximumAllocationPerQueue(A1).getMemorySize());
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("max allocation vcores A1",
|
assertEquals("max allocation vcores A1",
|
||||||
2,
|
2,
|
||||||
conf.getMaximumAllocationPerQueue(A1).getVirtualCores());
|
queueA1.getMaximumAllocation().getVirtualCores());
|
||||||
assertEquals("cluster max allocation MB",
|
assertEquals("cluster max allocation MB",
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getMemorySize());
|
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getMemorySize());
|
||||||
|
@ -3106,11 +3112,8 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
||||||
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getVirtualCores());
|
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getVirtualCores());
|
||||||
|
|
||||||
CSQueue rootQueue = cs.getRootQueue();
|
assertEquals("queue max allocation", 4096,
|
||||||
CSQueue queueA = findQueue(rootQueue, A);
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
CSQueue queueA1 = findQueue(queueA, A1);
|
|
||||||
assertEquals("queue max allocation", 4096, ((LeafQueue) queueA1)
|
|
||||||
.getMaximumAllocation().getMemorySize());
|
|
||||||
|
|
||||||
setMaxAllocMb(conf, A1, 6144);
|
setMaxAllocMb(conf, A1, 6144);
|
||||||
setMaxAllocVcores(conf, A1, 3);
|
setMaxAllocVcores(conf, A1, 3);
|
||||||
|
@ -3118,9 +3121,9 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
// conf will have changed but we shouldn't be able to change max allocation
|
// conf will have changed but we shouldn't be able to change max allocation
|
||||||
// for the actual queue
|
// for the actual queue
|
||||||
assertEquals("max allocation MB A1", 6144,
|
assertEquals("max allocation MB A1", 6144,
|
||||||
conf.getMaximumAllocationPerQueue(A1).getMemorySize());
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("max allocation vcores A1", 3,
|
assertEquals("max allocation vcores A1", 3,
|
||||||
conf.getMaximumAllocationPerQueue(A1).getVirtualCores());
|
queueA1.getMaximumAllocation().getVirtualCores());
|
||||||
assertEquals("max allocation MB cluster",
|
assertEquals("max allocation MB cluster",
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getMemorySize());
|
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getMemorySize());
|
||||||
|
@ -3128,9 +3131,9 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
||||||
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getVirtualCores());
|
ResourceUtils.fetchMaximumAllocationFromConfig(conf).getVirtualCores());
|
||||||
assertEquals("queue max allocation MB", 6144,
|
assertEquals("queue max allocation MB", 6144,
|
||||||
((LeafQueue) queueA1).getMaximumAllocation().getMemorySize());
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("queue max allocation vcores", 3,
|
assertEquals("queue max allocation vcores", 3,
|
||||||
((LeafQueue) queueA1).getMaximumAllocation().getVirtualCores());
|
queueA1.getMaximumAllocation().getVirtualCores());
|
||||||
assertEquals("max capability MB cluster",
|
assertEquals("max capability MB cluster",
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
cs.getMaximumResourceCapability().getMemorySize());
|
cs.getMaximumResourceCapability().getMemorySize());
|
||||||
|
@ -3216,17 +3219,17 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
CSQueue queueB2 = findQueue(queueB, B2);
|
CSQueue queueB2 = findQueue(queueB, B2);
|
||||||
|
|
||||||
assertEquals("queue A1 max allocation MB", 4096,
|
assertEquals("queue A1 max allocation MB", 4096,
|
||||||
((LeafQueue) queueA1).getMaximumAllocation().getMemorySize());
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("queue A1 max allocation vcores", 4,
|
assertEquals("queue A1 max allocation vcores", 4,
|
||||||
((LeafQueue) queueA1).getMaximumAllocation().getVirtualCores());
|
queueA1.getMaximumAllocation().getVirtualCores());
|
||||||
assertEquals("queue A2 max allocation MB", 10240,
|
assertEquals("queue A2 max allocation MB", 10240,
|
||||||
((LeafQueue) queueA2).getMaximumAllocation().getMemorySize());
|
queueA2.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("queue A2 max allocation vcores", 10,
|
assertEquals("queue A2 max allocation vcores", 10,
|
||||||
((LeafQueue) queueA2).getMaximumAllocation().getVirtualCores());
|
queueA2.getMaximumAllocation().getVirtualCores());
|
||||||
assertEquals("queue B2 max allocation MB", 10240,
|
assertEquals("queue B2 max allocation MB", 10240,
|
||||||
((LeafQueue) queueB2).getMaximumAllocation().getMemorySize());
|
queueB2.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("queue B2 max allocation vcores", 10,
|
assertEquals("queue B2 max allocation vcores", 10,
|
||||||
((LeafQueue) queueB2).getMaximumAllocation().getVirtualCores());
|
queueB2.getMaximumAllocation().getVirtualCores());
|
||||||
|
|
||||||
setMaxAllocMb(conf, 12288);
|
setMaxAllocMb(conf, 12288);
|
||||||
setMaxAllocVcores(conf, 12);
|
setMaxAllocVcores(conf, 12);
|
||||||
|
@ -3238,17 +3241,187 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
assertEquals("max allocation vcores in CS", 12,
|
assertEquals("max allocation vcores in CS", 12,
|
||||||
cs.getMaximumResourceCapability().getVirtualCores());
|
cs.getMaximumResourceCapability().getVirtualCores());
|
||||||
assertEquals("queue A1 max MB allocation", 4096,
|
assertEquals("queue A1 max MB allocation", 4096,
|
||||||
((LeafQueue) queueA1).getMaximumAllocation().getMemorySize());
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("queue A1 max vcores allocation", 4,
|
assertEquals("queue A1 max vcores allocation", 4,
|
||||||
((LeafQueue) queueA1).getMaximumAllocation().getVirtualCores());
|
queueA1.getMaximumAllocation().getVirtualCores());
|
||||||
assertEquals("queue A2 max MB allocation", 12288,
|
assertEquals("queue A2 max MB allocation", 12288,
|
||||||
((LeafQueue) queueA2).getMaximumAllocation().getMemorySize());
|
queueA2.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("queue A2 max vcores allocation", 12,
|
assertEquals("queue A2 max vcores allocation", 12,
|
||||||
((LeafQueue) queueA2).getMaximumAllocation().getVirtualCores());
|
queueA2.getMaximumAllocation().getVirtualCores());
|
||||||
assertEquals("queue B2 max MB allocation", 12288,
|
assertEquals("queue B2 max MB allocation", 12288,
|
||||||
((LeafQueue) queueB2).getMaximumAllocation().getMemorySize());
|
queueB2.getMaximumAllocation().getMemorySize());
|
||||||
assertEquals("queue B2 max vcores allocation", 12,
|
assertEquals("queue B2 max vcores allocation", 12,
|
||||||
((LeafQueue) queueB2).getMaximumAllocation().getVirtualCores());
|
queueB2.getMaximumAllocation().getVirtualCores());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueuesMaxAllocationInheritance() throws Exception {
|
||||||
|
// queue level max allocation is set by the queue configuration explicitly
|
||||||
|
// or inherits from the parent.
|
||||||
|
|
||||||
|
CapacityScheduler cs = new CapacityScheduler();
|
||||||
|
cs.setConf(new YarnConfiguration());
|
||||||
|
cs.setRMContext(resourceManager.getRMContext());
|
||||||
|
CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration();
|
||||||
|
setupQueueConfiguration(conf);
|
||||||
|
setMaxAllocMb(conf,
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB);
|
||||||
|
setMaxAllocVcores(conf,
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES);
|
||||||
|
|
||||||
|
// Test the child queue overrides
|
||||||
|
setMaxAllocation(conf, CapacitySchedulerConfiguration.ROOT,
|
||||||
|
"memory-mb=4096,vcores=2");
|
||||||
|
setMaxAllocation(conf, A1, "memory-mb=6144,vcores=2");
|
||||||
|
setMaxAllocation(conf, B, "memory-mb=5120, vcores=2");
|
||||||
|
setMaxAllocation(conf, B2, "memory-mb=1024, vcores=2");
|
||||||
|
|
||||||
|
cs.init(conf);
|
||||||
|
cs.start();
|
||||||
|
cs.reinitialize(conf, mockContext);
|
||||||
|
checkQueueCapacities(cs, A_CAPACITY, B_CAPACITY);
|
||||||
|
|
||||||
|
CSQueue rootQueue = cs.getRootQueue();
|
||||||
|
CSQueue queueA = findQueue(rootQueue, A);
|
||||||
|
CSQueue queueB = findQueue(rootQueue, B);
|
||||||
|
CSQueue queueA1 = findQueue(queueA, A1);
|
||||||
|
CSQueue queueA2 = findQueue(queueA, A2);
|
||||||
|
CSQueue queueB1 = findQueue(queueB, B1);
|
||||||
|
CSQueue queueB2 = findQueue(queueB, B2);
|
||||||
|
|
||||||
|
assertEquals("max capability MB in CS",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
|
cs.getMaximumResourceCapability().getMemorySize());
|
||||||
|
assertEquals("max capability vcores in CS",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
||||||
|
cs.getMaximumResourceCapability().getVirtualCores());
|
||||||
|
assertEquals("max allocation MB A1",
|
||||||
|
6144,
|
||||||
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
|
assertEquals("max allocation vcores A1",
|
||||||
|
2,
|
||||||
|
queueA1.getMaximumAllocation().getVirtualCores());
|
||||||
|
assertEquals("max allocation MB A2", 4096,
|
||||||
|
queueA2.getMaximumAllocation().getMemorySize());
|
||||||
|
assertEquals("max allocation vcores A2",
|
||||||
|
2,
|
||||||
|
queueA2.getMaximumAllocation().getVirtualCores());
|
||||||
|
assertEquals("max allocation MB B", 5120,
|
||||||
|
queueB.getMaximumAllocation().getMemorySize());
|
||||||
|
assertEquals("max allocation MB B1", 5120,
|
||||||
|
queueB1.getMaximumAllocation().getMemorySize());
|
||||||
|
assertEquals("max allocation MB B2", 1024,
|
||||||
|
queueB2.getMaximumAllocation().getMemorySize());
|
||||||
|
|
||||||
|
// Test get the max-allocation from different parent
|
||||||
|
unsetMaxAllocation(conf, A1);
|
||||||
|
unsetMaxAllocation(conf, B);
|
||||||
|
unsetMaxAllocation(conf, B1);
|
||||||
|
setMaxAllocation(conf, CapacitySchedulerConfiguration.ROOT,
|
||||||
|
"memory-mb=6144,vcores=2");
|
||||||
|
setMaxAllocation(conf, A, "memory-mb=8192,vcores=2");
|
||||||
|
|
||||||
|
cs.reinitialize(conf, mockContext);
|
||||||
|
|
||||||
|
assertEquals("max capability MB in CS",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
|
cs.getMaximumResourceCapability().getMemorySize());
|
||||||
|
assertEquals("max capability vcores in CS",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
||||||
|
cs.getMaximumResourceCapability().getVirtualCores());
|
||||||
|
assertEquals("max allocation MB A1",
|
||||||
|
8192,
|
||||||
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
|
assertEquals("max allocation vcores A1",
|
||||||
|
2,
|
||||||
|
queueA1.getMaximumAllocation().getVirtualCores());
|
||||||
|
assertEquals("max allocation MB B1",
|
||||||
|
6144,
|
||||||
|
queueB1.getMaximumAllocation().getMemorySize());
|
||||||
|
assertEquals("max allocation vcores B1",
|
||||||
|
2,
|
||||||
|
queueB1.getMaximumAllocation().getVirtualCores());
|
||||||
|
|
||||||
|
// Test the default
|
||||||
|
unsetMaxAllocation(conf, CapacitySchedulerConfiguration.ROOT);
|
||||||
|
unsetMaxAllocation(conf, A);
|
||||||
|
unsetMaxAllocation(conf, A1);
|
||||||
|
cs.reinitialize(conf, mockContext);
|
||||||
|
|
||||||
|
assertEquals("max capability MB in CS",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
|
cs.getMaximumResourceCapability().getMemorySize());
|
||||||
|
assertEquals("max capability vcores in CS",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
||||||
|
cs.getMaximumResourceCapability().getVirtualCores());
|
||||||
|
assertEquals("max allocation MB A1",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
|
queueA1.getMaximumAllocation().getMemorySize());
|
||||||
|
assertEquals("max allocation vcores A1",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
||||||
|
queueA1.getMaximumAllocation().getVirtualCores());
|
||||||
|
assertEquals("max allocation MB A2",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
|
||||||
|
queueA2.getMaximumAllocation().getMemorySize());
|
||||||
|
assertEquals("max allocation vcores A2",
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
|
||||||
|
queueA2.getMaximumAllocation().getVirtualCores());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVerifyQueuesMaxAllocationConf() throws Exception {
|
||||||
|
// queue level max allocation can't exceed the cluster setting
|
||||||
|
|
||||||
|
CapacityScheduler cs = new CapacityScheduler();
|
||||||
|
cs.setConf(new YarnConfiguration());
|
||||||
|
cs.setRMContext(resourceManager.getRMContext());
|
||||||
|
CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration();
|
||||||
|
setupQueueConfiguration(conf);
|
||||||
|
setMaxAllocMb(conf,
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB);
|
||||||
|
setMaxAllocVcores(conf,
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES);
|
||||||
|
|
||||||
|
long largerMem =
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB + 1024;
|
||||||
|
long largerVcores =
|
||||||
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES+10;
|
||||||
|
|
||||||
|
cs.init(conf);
|
||||||
|
cs.start();
|
||||||
|
cs.reinitialize(conf, mockContext);
|
||||||
|
checkQueueCapacities(cs, A_CAPACITY, B_CAPACITY);
|
||||||
|
|
||||||
|
setMaxAllocation(conf, CapacitySchedulerConfiguration.ROOT,
|
||||||
|
"memory-mb=" + largerMem + ",vcores=2");
|
||||||
|
try {
|
||||||
|
cs.reinitialize(conf, mockContext);
|
||||||
|
fail("Queue Root maximum allocation can't exceed the cluster setting");
|
||||||
|
} catch(Exception e) {
|
||||||
|
assertTrue("maximum allocation exception",
|
||||||
|
e.getCause().getMessage().contains("maximum allocation"));
|
||||||
|
}
|
||||||
|
|
||||||
|
setMaxAllocation(conf, CapacitySchedulerConfiguration.ROOT,
|
||||||
|
"memory-mb=4096,vcores=2");
|
||||||
|
setMaxAllocation(conf, A, "memory-mb=6144,vcores=2");
|
||||||
|
setMaxAllocation(conf, A1, "memory-mb=" + largerMem + ",vcores=2");
|
||||||
|
try {
|
||||||
|
cs.reinitialize(conf, mockContext);
|
||||||
|
fail("Queue A1 maximum allocation can't exceed the cluster setting");
|
||||||
|
} catch(Exception e) {
|
||||||
|
assertTrue("maximum allocation exception",
|
||||||
|
e.getCause().getMessage().contains("maximum allocation"));
|
||||||
|
}
|
||||||
|
setMaxAllocation(conf, A1, "memory-mb=8192" + ",vcores=" + largerVcores);
|
||||||
|
try {
|
||||||
|
cs.reinitialize(conf, mockContext);
|
||||||
|
fail("Queue A1 maximum allocation can't exceed the cluster setting");
|
||||||
|
} catch(Exception e) {
|
||||||
|
assertTrue("maximum allocation exception",
|
||||||
|
e.getCause().getMessage().contains("maximum allocation"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitContainerAllocated(MockAM am, int mem, int nContainer,
|
private void waitContainerAllocated(MockAM am, int mem, int nContainer,
|
||||||
|
@ -4103,6 +4276,20 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
||||||
conf.setInt(propName, maxAllocVcores);
|
conf.setInt(propName, maxAllocVcores);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setMaxAllocation(CapacitySchedulerConfiguration conf,
|
||||||
|
String queueName, String maxAllocation) {
|
||||||
|
String propName = CapacitySchedulerConfiguration.getQueuePrefix(queueName)
|
||||||
|
+ MAXIMUM_ALLOCATION;
|
||||||
|
conf.set(propName, maxAllocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unsetMaxAllocation(CapacitySchedulerConfiguration conf,
|
||||||
|
String queueName) {
|
||||||
|
String propName = CapacitySchedulerConfiguration.getQueuePrefix(queueName)
|
||||||
|
+ MAXIMUM_ALLOCATION;
|
||||||
|
conf.unset(propName);
|
||||||
|
}
|
||||||
|
|
||||||
private void sentRMContainerLaunched(MockRM rm, ContainerId containerId) {
|
private void sentRMContainerLaunched(MockRM rm, ContainerId containerId) {
|
||||||
CapacityScheduler cs = (CapacityScheduler) rm.getResourceScheduler();
|
CapacityScheduler cs = (CapacityScheduler) rm.getResourceScheduler();
|
||||||
RMContainer rmContainer = cs.getRMContainer(containerId);
|
RMContainer rmContainer = cs.getRMContainer(containerId);
|
||||||
|
|
Loading…
Reference in New Issue