YARN-6788. [YARN-3926] Improve performance of resource profile branch

(Contributed by Sunil Govindan via Daniel Templeton)

(cherry picked from commit 3aeaafecb8)
This commit is contained in:
Daniel Templeton 2017-08-04 08:42:34 -07:00 committed by Jonathan Hung
parent 1dc66dbb3f
commit d8f388652e
18 changed files with 627 additions and 458 deletions

View File

@ -615,4 +615,22 @@
<Bug pattern="IS2_INCONSISTENT_SYNC" /> <Bug pattern="IS2_INCONSISTENT_SYNC" />
</Match> </Match>
<!-- Ignore MS_EXPOSE_REP -->
<Match>
<Class name="org.apache.hadoop.yarn.util.resource.ResourceUtils" />
<Method name="getResourceTypesArray" />
<Bug pattern="MS_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.apache.hadoop.yarn.util.resource.ResourceUtils" />
<Method name="getResourceNamesArray" />
<Bug pattern="MS_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.apache.hadoop.yarn.api.records.impl.BaseResource" />
<Method name="getResources" />
<Bug pattern="EI_EXPOSE_REP" />
</Match>
</FindBugsFilter> </FindBugsFilter>

View File

@ -18,6 +18,8 @@
package org.apache.hadoop.yarn.api.records; package org.apache.hadoop.yarn.api.records;
import java.util.Arrays;
import org.apache.commons.lang.NotImplementedException; import org.apache.commons.lang.NotImplementedException;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceAudience.Public; import org.apache.hadoop.classification.InterfaceAudience.Public;
@ -25,13 +27,10 @@ import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.classification.InterfaceStability.Evolving; import org.apache.hadoop.classification.InterfaceStability.Evolving;
import org.apache.hadoop.classification.InterfaceStability.Stable; import org.apache.hadoop.classification.InterfaceStability.Stable;
import org.apache.hadoop.yarn.api.ApplicationMasterProtocol; import org.apache.hadoop.yarn.api.ApplicationMasterProtocol;
import org.apache.hadoop.yarn.api.records.impl.BaseResource;
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException; import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.util.Records; import org.apache.hadoop.yarn.util.Records;
import org.apache.hadoop.yarn.util.resource.ResourceUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/** /**
* <p><code>Resource</code> models a set of computer resources in the * <p><code>Resource</code> models a set of computer resources in the
@ -60,97 +59,49 @@ import java.util.Map;
@Stable @Stable
public abstract class Resource implements Comparable<Resource> { public abstract class Resource implements Comparable<Resource> {
private static Resource tmpResource = Records.newRecord(Resource.class); protected static final String MEMORY = ResourceInformation.MEMORY_MB.getName();
protected static final String VCORES = ResourceInformation.VCORES.getName();
private static class SimpleResource extends Resource {
private long memory;
private long vcores;
private Map<String, ResourceInformation> resourceInformationMap;
SimpleResource(long memory, long vcores) {
this.memory = memory;
this.vcores = vcores;
}
@Override
public int getMemory() {
return castToIntSafely(memory);
}
@Override
public void setMemory(int memory) {
this.memory = memory;
}
@Override
public long getMemorySize() {
return memory;
}
@Override
public void setMemorySize(long memory) {
this.memory = memory;
}
@Override
public int getVirtualCores() {
return castToIntSafely(vcores);
}
@Override
public void setVirtualCores(int vcores) {
this.vcores = vcores;
}
@Override
public Map<String, ResourceInformation> getResources() {
if (resourceInformationMap == null) {
resourceInformationMap = new HashMap<>();
resourceInformationMap.put(ResourceInformation.MEMORY_MB.getName(),
ResourceInformation.newInstance(ResourceInformation.MEMORY_MB));
resourceInformationMap.put(ResourceInformation.VCORES.getName(),
ResourceInformation.newInstance(ResourceInformation.VCORES));
}
resourceInformationMap.get(ResourceInformation.MEMORY_MB.getName())
.setValue(this.memory);
resourceInformationMap.get(ResourceInformation.VCORES.getName())
.setValue(this.vcores);
return Collections.unmodifiableMap(resourceInformationMap);
}
}
@Public @Public
@Stable @Stable
public static Resource newInstance(int memory, int vCores) { public static Resource newInstance(int memory, int vCores) {
if (tmpResource.getResources().size() > 2) { if (ResourceUtils.getResourceTypesArray().length > 2) {
Resource ret = Records.newRecord(Resource.class); Resource ret = Records.newRecord(Resource.class);
ret.setMemorySize(memory); ret.setMemorySize(memory);
ret.setVirtualCores(vCores); ret.setVirtualCores(vCores);
return ret; return ret;
} }
return new SimpleResource(memory, vCores); return new BaseResource(memory, vCores);
} }
@Public @Public
@Stable @Stable
public static Resource newInstance(long memory, int vCores) { public static Resource newInstance(long memory, int vCores) {
if (tmpResource.getResources().size() > 2) { if (ResourceUtils.getResourceTypesArray().length > 2) {
Resource ret = Records.newRecord(Resource.class); Resource ret = Records.newRecord(Resource.class);
ret.setMemorySize(memory); ret.setMemorySize(memory);
ret.setVirtualCores(vCores); ret.setVirtualCores(vCores);
return ret; return ret;
} }
return new SimpleResource(memory, vCores); return new BaseResource(memory, vCores);
} }
@InterfaceAudience.Private @InterfaceAudience.Private
@InterfaceStability.Unstable @InterfaceStability.Unstable
public static Resource newInstance(Resource resource) { public static Resource newInstance(Resource resource) {
Resource ret = Resource.newInstance(0, 0); Resource ret = Resource.newInstance(resource.getMemorySize(),
resource.getVirtualCores());
if (ResourceUtils.getResourceTypesArray().length > 2) {
Resource.copy(resource, ret); Resource.copy(resource, ret);
}
return ret; return ret;
} }
@InterfaceAudience.Private @InterfaceAudience.Private
@InterfaceStability.Unstable @InterfaceStability.Unstable
public static void copy(Resource source, Resource dest) { public static void copy(Resource source, Resource dest) {
for (Map.Entry<String, ResourceInformation> entry : source.getResources() for (ResourceInformation entry : source.getResources()) {
.entrySet()) { dest.setResourceInformation(entry.getName(), entry);
dest.setResourceInformation(entry.getKey(), entry.getValue());
} }
} }
@ -251,25 +202,26 @@ public abstract class Resource implements Comparable<Resource> {
*/ */
@Public @Public
@Evolving @Evolving
public abstract Map<String, ResourceInformation> getResources(); public abstract ResourceInformation[] getResources();
/** /**
* Get ResourceInformation for a specified resource. * Get ResourceInformation for a specified resource.
* *
* @param resource name of the resource * @param resource name of the resource
* @return the ResourceInformation object for the resource * @return the ResourceInformation object for the resource
* @throws YarnException if the resource can't be found * @throws ResourceNotFoundException if the resource can't be found
*/ */
@Public @Public
@Evolving @Evolving
public ResourceInformation getResourceInformation(String resource) public ResourceInformation getResourceInformation(String resource)
throws YarnException { throws ResourceNotFoundException {
if (getResources().containsKey(resource)) { Integer index = ResourceUtils.getResourceTypeIndex().get(resource);
return getResources().get(resource); ResourceInformation[] resources = getResources();
if (index != null) {
return resources[index];
} }
throw new YarnException( throw new ResourceNotFoundException("Unknown resource '" + resource
"Unknown resource '" + resource + "'. Known resources are " + "'. Known resources are " + Arrays.toString(resources));
+ getResources().keySet());
} }
/** /**
@ -278,17 +230,13 @@ public abstract class Resource implements Comparable<Resource> {
* *
* @param resource name of the resource * @param resource name of the resource
* @return the value for the resource * @return the value for the resource
* @throws YarnException if the resource can't be found * @throws ResourceNotFoundException if the resource can't be found
*/ */
@Public @Public
@Evolving @Evolving
public Long getResourceValue(String resource) throws YarnException { public long getResourceValue(String resource)
if (getResources().containsKey(resource)) { throws ResourceNotFoundException {
return getResources().get(resource).getValue(); return getResourceInformation(resource).getValue();
}
throw new YarnException(
"Unknown resource '" + resource + "'. Known resources are "
+ getResources().keySet());
} }
/** /**
@ -301,23 +249,18 @@ public abstract class Resource implements Comparable<Resource> {
@Public @Public
@Evolving @Evolving
public void setResourceInformation(String resource, public void setResourceInformation(String resource,
ResourceInformation resourceInformation) throws ResourceNotFoundException { ResourceInformation resourceInformation)
if (resource.equals(ResourceInformation.MEMORY_MB.getName())) { throws ResourceNotFoundException {
if (resource.equals(MEMORY)) {
this.setMemorySize(resourceInformation.getValue()); this.setMemorySize(resourceInformation.getValue());
return; return;
} }
if (resource.equals(ResourceInformation.VCORES.getName())) { if (resource.equals(VCORES)) {
this.setVirtualCores((int) resourceInformation.getValue()); this.setVirtualCores((int) resourceInformation.getValue());
return; return;
} }
if (getResources().containsKey(resource)) { ResourceInformation storedResourceInfo = getResourceInformation(resource);
ResourceInformation ResourceInformation.copy(resourceInformation, storedResourceInfo);
.copy(resourceInformation, getResources().get(resource));
return;
}
throw new ResourceNotFoundException(
"Unknown resource '" + resource + "'. Known resources are "
+ getResources().keySet());
} }
/** /**
@ -332,21 +275,17 @@ public abstract class Resource implements Comparable<Resource> {
@Evolving @Evolving
public void setResourceValue(String resource, Long value) public void setResourceValue(String resource, Long value)
throws ResourceNotFoundException { throws ResourceNotFoundException {
if (resource.equals(ResourceInformation.MEMORY_MB.getName())) { if (resource.equals(MEMORY)) {
this.setMemorySize(value); this.setMemorySize(value);
return; return;
} }
if (resource.equals(ResourceInformation.VCORES.getName())) { if (resource.equals(VCORES)) {
this.setVirtualCores(value.intValue()); this.setVirtualCores(value.intValue());
return; return;
} }
if (getResources().containsKey(resource)) {
getResources().get(resource).setValue(value); ResourceInformation storedResourceInfo = getResourceInformation(resource);
return; storedResourceInfo.setValue(value);
}
throw new ResourceNotFoundException(
"Unknown resource '" + resource + "'. Known resources are "
+ getResources().keySet());
} }
@Override @Override
@ -356,13 +295,10 @@ public abstract class Resource implements Comparable<Resource> {
int result = (int) (939769357 int result = (int) (939769357
+ getMemorySize()); // prime * result = 939769357 initially + getMemorySize()); // prime * result = 939769357 initially
result = prime * result + getVirtualCores(); result = prime * result + getVirtualCores();
for (Map.Entry<String, ResourceInformation> entry : getResources() for (ResourceInformation entry : getResources()) {
.entrySet()) { if (!entry.getName().equals(MEMORY) && !entry.getName().equals(VCORES)) {
if (entry.getKey().equals(ResourceInformation.MEMORY_MB.getName()) result = prime * result + entry.hashCode();
|| entry.getKey().equals(ResourceInformation.VCORES.getName())) {
continue;
} }
result = prime * result + entry.getValue().hashCode();
} }
return result; return result;
} }
@ -379,11 +315,26 @@ public abstract class Resource implements Comparable<Resource> {
return false; return false;
} }
Resource other = (Resource) obj; Resource other = (Resource) obj;
if (getMemorySize() != other.getMemorySize() || getVirtualCores() != other if (getMemorySize() != other.getMemorySize()
.getVirtualCores()) { || getVirtualCores() != other.getVirtualCores()) {
return false; return false;
} }
return this.getResources().equals(other.getResources());
ResourceInformation[] myVectors = getResources();
ResourceInformation[] otherVectors = other.getResources();
if (myVectors.length != otherVectors.length) {
return false;
}
for (int i = 0; i < myVectors.length; i++) {
ResourceInformation a = myVectors[i];
ResourceInformation b = otherVectors[i];
if ((a != b) && ((a == null) || !a.equals(b))) {
return false;
}
}
return true;
} }
@Override @Override
@ -391,21 +342,20 @@ public abstract class Resource implements Comparable<Resource> {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("<memory:").append(getMemorySize()).append(", vCores:") sb.append("<memory:").append(getMemorySize()).append(", vCores:")
.append(getVirtualCores()); .append(getVirtualCores());
for (Map.Entry<String, ResourceInformation> entry : getResources() for (ResourceInformation entry : getResources()) {
.entrySet()) { if (entry.getName().equals(MEMORY)
if (entry.getKey().equals(ResourceInformation.MEMORY_MB.getName()) && entry.getUnits()
&& entry.getValue().getUnits()
.equals(ResourceInformation.MEMORY_MB.getUnits())) { .equals(ResourceInformation.MEMORY_MB.getUnits())) {
continue; continue;
} }
if (entry.getKey().equals(ResourceInformation.VCORES.getName()) if (entry.getName().equals(VCORES)
&& entry.getValue().getUnits() && entry.getUnits()
.equals(ResourceInformation.VCORES.getUnits())) { .equals(ResourceInformation.VCORES.getUnits())) {
continue; continue;
} }
sb.append(", ").append(entry.getKey()).append(": ") sb.append(", ").append(entry.getName()).append(": ")
.append(entry.getValue().getValue()) .append(entry.getValue())
.append(entry.getValue().getUnits()); .append(entry.getUnits());
} }
sb.append(">"); sb.append(">");
return sb.toString(); return sb.toString();
@ -413,28 +363,30 @@ public abstract class Resource implements Comparable<Resource> {
@Override @Override
public int compareTo(Resource other) { public int compareTo(Resource other) {
Map<String, ResourceInformation> thisResources, otherResources; ResourceInformation[] thisResources = this.getResources();
thisResources = this.getResources(); ResourceInformation[] otherResources = other.getResources();
otherResources = other.getResources();
long diff = thisResources.size() - otherResources.size();
if (diff == 0) {
// compare memory and vcores first(in that order) to preserve // compare memory and vcores first(in that order) to preserve
// existing behaviour // existing behaviour
if (thisResources.keySet().equals(otherResources.keySet())) { long diff = this.getMemorySize() - other.getMemorySize();
diff = this.getMemorySize() - other.getMemorySize();
if (diff == 0) { if (diff == 0) {
diff = this.getVirtualCores() - other.getVirtualCores(); diff = this.getVirtualCores() - other.getVirtualCores();
} }
if (diff == 0) { if (diff == 0) {
for (Map.Entry<String, ResourceInformation> entry : thisResources diff = thisResources.length - otherResources.length;
.entrySet()) { if (diff == 0) {
if (entry.getKey().equals(ResourceInformation.MEMORY_MB.getName()) int maxLength = ResourceUtils.getResourceTypesArray().length;
|| entry.getKey() for (int i = 0; i < maxLength; i++) {
.equals(ResourceInformation.VCORES.getName())) { // For memory and vcores, we can skip the loop as it's already
// compared.
if (i < 2) {
continue; continue;
} }
diff =
entry.getValue().compareTo(otherResources.get(entry.getKey())); ResourceInformation entry = thisResources[i];
ResourceInformation otherEntry = otherResources[i];
if (entry.getName().equals(otherEntry.getName())) {
diff = entry.compareTo(otherEntry);
if (diff != 0) { if (diff != 0) {
break; break;
} }

View File

@ -242,10 +242,15 @@ public class ResourceInformation implements Comparable<ResourceInformation> {
return false; return false;
} }
ResourceInformation r = (ResourceInformation) obj; ResourceInformation r = (ResourceInformation) obj;
int cmp = if (!this.name.equals(r.getName())
UnitsConversionUtil.compare(this.units, this.value, r.units, r.value); || !this.resourceType.equals(r.getResourceType())) {
return this.name.equals(r.getName()) && this.resourceType return false;
.equals(r.getResourceType()) && (cmp == 0); }
if (this.units.equals(r.units)) {
return this.value == r.value;
}
return (UnitsConversionUtil.compare(this.units, this.value, r.units,
r.value) == 0);
} }
@Override @Override

View File

@ -0,0 +1,133 @@
/**
* 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.api.records.impl;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.api.records.ResourceInformation;
import java.util.Arrays;
/**
* <p>
* <code>BaseResource</code> extends Resource to handle base resources such
* as memory and CPU.
* TODO: We have a long term plan to use AbstractResource when additional
* resource types are to be handled as well.
* </p>
*
* <p>
* Currently it models both <em>memory</em> and <em>CPU</em>.
* </p>
*
* <p>
* The unit for memory is megabytes. CPU is modeled with virtual cores (vcores),
* a unit for expressing parallelism. A node's capacity should be configured
* with virtual cores equal to its number of physical cores. A container should
* be requested with the number of cores it can saturate, i.e. the average
* number of threads it expects to have runnable at a time.
* </p>
*
* <p>
* Virtual cores take integer values and thus currently CPU-scheduling is very
* coarse. A complementary axis for CPU requests that represents processing
* power will likely be added in the future to enable finer-grained resource
* configuration.
* </p>
*
* @see Resource
*/
@Public
@Unstable
public class BaseResource extends Resource {
private ResourceInformation memoryResInfo;
private ResourceInformation vcoresResInfo;
protected ResourceInformation[] resources = null;
protected ResourceInformation[] readOnlyResources = null;
protected enum MandatoryResources {
MEMORY(0), VCORES(1);
private final int id;
MandatoryResources(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
}
public BaseResource() {
// Base constructor.
}
public BaseResource(long memory, long vcores) {
this.memoryResInfo = ResourceInformation.newInstance(MEMORY,
ResourceInformation.MEMORY_MB.getUnits(), memory);
this.vcoresResInfo = ResourceInformation.newInstance(VCORES, "", vcores);
resources = new ResourceInformation[MandatoryResources.values().length];
readOnlyResources = new ResourceInformation[MandatoryResources
.values().length];
resources[MandatoryResources.MEMORY.id] = memoryResInfo;
resources[MandatoryResources.VCORES.id] = vcoresResInfo;
readOnlyResources = Arrays.copyOf(resources, resources.length);
}
@Override
@SuppressWarnings("deprecation")
public int getMemory() {
return (int) memoryResInfo.getValue();
}
@Override
@SuppressWarnings("deprecation")
public void setMemory(int memory) {
this.memoryResInfo.setValue(memory);
}
@Override
public long getMemorySize() {
return memoryResInfo.getValue();
}
@Override
public void setMemorySize(long memory) {
this.memoryResInfo.setValue(memory);
}
@Override
public int getVirtualCores() {
return (int) vcoresResInfo.getValue();
}
@Override
public void setVirtualCores(int vcores) {
this.vcoresResInfo.setValue(vcores);
}
@Override
public ResourceInformation[] getResources() {
return readOnlyResources;
}
}

View File

@ -0,0 +1,22 @@
/*
* 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.
*/
@InterfaceAudience.Public
@InterfaceStability.Unstable
package org.apache.hadoop.yarn.api.records.impl;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

View File

@ -186,11 +186,11 @@ public class UnitsConversionUtil {
if (!KNOWN_UNITS.contains(unitB)) { if (!KNOWN_UNITS.contains(unitB)) {
throw new IllegalArgumentException("Unknown unit '" + unitB + "'"); throw new IllegalArgumentException("Unknown unit '" + unitB + "'");
} }
if (unitA.equals(unitB)) {
return Long.compare(valueA, valueB);
}
Converter unitAC = getConverter(unitA); Converter unitAC = getConverter(unitA);
Converter unitBC = getConverter(unitB); Converter unitBC = getConverter(unitB);
if (unitA.equals(unitB)) {
return Long.valueOf(valueA).compareTo(valueB);
}
int unitAPos = SORTED_UNITS.indexOf(unitA); int unitAPos = SORTED_UNITS.indexOf(unitA);
int unitBPos = SORTED_UNITS.indexOf(unitB); int unitBPos = SORTED_UNITS.indexOf(unitB);
try { try {
@ -201,7 +201,7 @@ public class UnitsConversionUtil {
} else { } else {
tmpA = convert(unitA, unitB, valueA); tmpA = convert(unitA, unitB, valueA);
} }
return Long.valueOf(tmpA).compareTo(tmpB); return Long.compare(tmpA, tmpB);
} catch (IllegalArgumentException ie) { } catch (IllegalArgumentException ie) {
BigInteger tmpA = BigInteger.valueOf(valueA); BigInteger tmpA = BigInteger.valueOf(valueA);
BigInteger tmpB = BigInteger.valueOf(valueB); BigInteger tmpB = BigInteger.valueOf(valueB);

View File

@ -42,6 +42,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Helper class to read the resource-types to be supported by the system. * Helper class to read the resource-types to be supported by the system.
@ -65,11 +66,14 @@ public class ResourceUtils {
DISALLOWED_NAMES.add(VCORES); DISALLOWED_NAMES.add(VCORES);
} }
private static volatile Object lock; private static volatile boolean initializedResources = false;
private static Map<String, ResourceInformation> readOnlyResources; private static final Map<String, Integer> RESOURCE_NAME_TO_INDEX =
private static volatile Object nodeLock; new ConcurrentHashMap<String, Integer>();
private static Map<String, ResourceInformation> readOnlyNodeResources; private static volatile Map<String, ResourceInformation> resourceTypes;
private static volatile String[] resourceNamesArray;
private static volatile ResourceInformation[] resourceTypesArray;
private static volatile boolean initializedNodeResources = false;
private static volatile Map<String, ResourceInformation> readOnlyNodeResources;
static final Log LOG = LogFactory.getLog(ResourceUtils.class); static final Log LOG = LogFactory.getLog(ResourceUtils.class);
@ -127,21 +131,17 @@ public class ResourceUtils {
private static void setMinimumAllocationForMandatoryResources( private static void setMinimumAllocationForMandatoryResources(
Map<String, ResourceInformation> res, Configuration conf) { Map<String, ResourceInformation> res, Configuration conf) {
String[][] resourceTypesKeys = String[][] resourceTypesKeys = {
{ {ResourceInformation.MEMORY_MB.getName(),
{ ResourceInformation.MEMORY_MB.getName(),
YarnConfiguration.RM_SCHEDULER_MINIMUM_ALLOCATION_MB, YarnConfiguration.RM_SCHEDULER_MINIMUM_ALLOCATION_MB,
String.valueOf( String.valueOf(
YarnConfiguration.DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_MB), YarnConfiguration.DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_MB),
ResourceInformation.MEMORY_MB.getName() ResourceInformation.MEMORY_MB.getName()},
}, {ResourceInformation.VCORES.getName(),
{ ResourceInformation.VCORES.getName(),
YarnConfiguration.RM_SCHEDULER_MINIMUM_ALLOCATION_VCORES, YarnConfiguration.RM_SCHEDULER_MINIMUM_ALLOCATION_VCORES,
String.valueOf( String.valueOf(
YarnConfiguration.DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_VCORES), YarnConfiguration.DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_VCORES),
ResourceInformation.VCORES.getName() ResourceInformation.VCORES.getName()}};
}
};
for (String[] arr : resourceTypesKeys) { for (String[] arr : resourceTypesKeys) {
String resourceTypesKey = String resourceTypesKey =
YarnConfiguration.RESOURCE_TYPES + "." + arr[0] + MINIMUM_ALLOCATION; YarnConfiguration.RESOURCE_TYPES + "." + arr[0] + MINIMUM_ALLOCATION;
@ -166,23 +166,17 @@ public class ResourceUtils {
private static void setMaximumAllocationForMandatoryResources( private static void setMaximumAllocationForMandatoryResources(
Map<String, ResourceInformation> res, Configuration conf) { Map<String, ResourceInformation> res, Configuration conf) {
String[][] resourceTypesKeys = String[][] resourceTypesKeys = {
{ {ResourceInformation.MEMORY_MB.getName(),
{
ResourceInformation.MEMORY_MB.getName(),
YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_MB, YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_MB,
String.valueOf( String.valueOf(
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB), YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB),
ResourceInformation.MEMORY_MB.getName() ResourceInformation.MEMORY_MB.getName()},
}, {ResourceInformation.VCORES.getName(),
{
ResourceInformation.VCORES.getName(),
YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES, YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES,
String.valueOf( String.valueOf(
YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES), YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES),
ResourceInformation.VCORES.getName() ResourceInformation.VCORES.getName()}};
}
};
for (String[] arr : resourceTypesKeys) { for (String[] arr : resourceTypesKeys) {
String resourceTypesKey = String resourceTypesKey =
YarnConfiguration.RESOURCE_TYPES + "." + arr[0] + MAXIMUM_ALLOCATION; YarnConfiguration.RESOURCE_TYPES + "." + arr[0] + MAXIMUM_ALLOCATION;
@ -251,7 +245,50 @@ public class ResourceUtils {
addManadtoryResources(resourceInformationMap); addManadtoryResources(resourceInformationMap);
setMinimumAllocationForMandatoryResources(resourceInformationMap, conf); setMinimumAllocationForMandatoryResources(resourceInformationMap, conf);
setMaximumAllocationForMandatoryResources(resourceInformationMap, conf); setMaximumAllocationForMandatoryResources(resourceInformationMap, conf);
readOnlyResources = Collections.unmodifiableMap(resourceInformationMap); resourceTypes = Collections.unmodifiableMap(resourceInformationMap);
updateKnownResources();
updateResourceTypeIndex();
}
private static void updateKnownResources() {
// Update resource names.
resourceNamesArray = new String[resourceTypes.size()];
resourceTypesArray = new ResourceInformation[resourceTypes.size()];
int index = 2;
for (ResourceInformation resInfo : resourceTypes.values()) {
if (resInfo.getName().equals(MEMORY)) {
resourceTypesArray[0] = ResourceInformation
.newInstance(resourceTypes.get(MEMORY));
resourceNamesArray[0] = MEMORY;
} else if (resInfo.getName().equals(VCORES)) {
resourceTypesArray[1] = ResourceInformation
.newInstance(resourceTypes.get(VCORES));
resourceNamesArray[1] = VCORES;
} else {
resourceTypesArray[index] = ResourceInformation.newInstance(resInfo);
resourceNamesArray[index] = resInfo.getName();
index++;
}
}
}
private static void updateResourceTypeIndex() {
RESOURCE_NAME_TO_INDEX.clear();
for (int index = 0; index < resourceTypesArray.length; index++) {
ResourceInformation resInfo = resourceTypesArray[index];
RESOURCE_NAME_TO_INDEX.put(resInfo.getName(), index);
}
}
/**
* Get associate index of resource types such memory, cpu etc.
* This could help to access each resource types in a resource faster.
* @return Index map for all Resource Types.
*/
public static Map<String, Integer> getResourceTypeIndex() {
return RESOURCE_NAME_TO_INDEX;
} }
/** /**
@ -264,6 +301,22 @@ public class ResourceUtils {
YarnConfiguration.RESOURCE_TYPES_CONFIGURATION_FILE); YarnConfiguration.RESOURCE_TYPES_CONFIGURATION_FILE);
} }
/**
* Get resource names array, this is mostly for performance perspective. Never
* modify returned array.
*
* @return resourceNamesArray
*/
public static String[] getResourceNamesArray() {
getResourceTypes(null, YarnConfiguration.RESOURCE_TYPES_CONFIGURATION_FILE);
return resourceNamesArray;
}
public static ResourceInformation[] getResourceTypesArray() {
getResourceTypes(null, YarnConfiguration.RESOURCE_TYPES_CONFIGURATION_FILE);
return resourceTypesArray;
}
private static Map<String, ResourceInformation> getResourceTypes( private static Map<String, ResourceInformation> getResourceTypes(
Configuration conf) { Configuration conf) {
return getResourceTypes(conf, return getResourceTypes(conf,
@ -272,10 +325,9 @@ public class ResourceUtils {
private static Map<String, ResourceInformation> getResourceTypes( private static Map<String, ResourceInformation> getResourceTypes(
Configuration conf, String resourceFile) { Configuration conf, String resourceFile) {
if (lock == null) { if (!initializedResources) {
synchronized (ResourceUtils.class) {
if (lock == null) {
synchronized (ResourceUtils.class) { synchronized (ResourceUtils.class) {
if (!initializedResources) {
Map<String, ResourceInformation> resources = new HashMap<>(); Map<String, ResourceInformation> resources = new HashMap<>();
if (conf == null) { if (conf == null) {
conf = new YarnConfiguration(); conf = new YarnConfiguration();
@ -284,18 +336,17 @@ public class ResourceUtils {
addResourcesFileToConf(resourceFile, conf); addResourcesFileToConf(resourceFile, conf);
LOG.debug("Found " + resourceFile + ", adding to configuration"); LOG.debug("Found " + resourceFile + ", adding to configuration");
initializeResourcesMap(conf, resources); initializeResourcesMap(conf, resources);
lock = new Object(); initializedResources = true;
} catch (FileNotFoundException fe) { } catch (FileNotFoundException fe) {
LOG.info("Unable to find '" + resourceFile LOG.info("Unable to find '" + resourceFile
+ "'. Falling back to memory and vcores as resources", fe); + "'. Falling back to memory and vcores as resources", fe);
initializeResourcesMap(conf, resources); initializeResourcesMap(conf, resources);
lock = new Object(); initializedResources = true;
} }
} }
} }
} }
} return resourceTypes;
return readOnlyResources;
} }
private static InputStream getConfInputStream(String resourceFile, private static InputStream getConfInputStream(String resourceFile,
@ -341,13 +392,15 @@ public class ResourceUtils {
} }
@VisibleForTesting @VisibleForTesting
static void resetResourceTypes() { synchronized static void resetResourceTypes() {
lock = null; initializedResources = false;
} }
@VisibleForTesting @VisibleForTesting
public static void resetResourceTypes(Configuration conf) { public static void resetResourceTypes(Configuration conf) {
lock = null; synchronized (ResourceUtils.class) {
initializedResources = false;
}
getResourceTypes(conf); getResourceTypes(conf);
} }
@ -375,17 +428,17 @@ public class ResourceUtils {
*/ */
public static Map<String, ResourceInformation> getNodeResourceInformation( public static Map<String, ResourceInformation> getNodeResourceInformation(
Configuration conf) { Configuration conf) {
if (nodeLock == null) { if (!initializedNodeResources) {
synchronized (ResourceUtils.class) { synchronized (ResourceUtils.class) {
if (nodeLock == null) { if (!initializedNodeResources) {
synchronized (ResourceUtils.class) { Map<String, ResourceInformation> nodeResources = initializeNodeResourceInformation(
Map<String, ResourceInformation> nodeResources = conf);
initializeNodeResourceInformation(conf);
addManadtoryResources(nodeResources); addManadtoryResources(nodeResources);
checkMandatatoryResources(nodeResources); checkMandatatoryResources(nodeResources);
setMinimumAllocationForMandatoryResources(nodeResources, conf);
setMaximumAllocationForMandatoryResources(nodeResources, conf);
readOnlyNodeResources = Collections.unmodifiableMap(nodeResources); readOnlyNodeResources = Collections.unmodifiableMap(nodeResources);
nodeLock = new Object(); initializedNodeResources = true;
}
} }
} }
} }
@ -433,28 +486,24 @@ public class ResourceUtils {
@VisibleForTesting @VisibleForTesting
synchronized public static void resetNodeResources() { synchronized public static void resetNodeResources() {
nodeLock = null; initializedNodeResources = false;
} }
public static Resource getResourceTypesMinimumAllocation() { public static Resource getResourceTypesMinimumAllocation() {
Map<String, ResourceInformation> resourceTypes = getResourceTypes();
Resource ret = Resource.newInstance(0, 0); Resource ret = Resource.newInstance(0, 0);
for (Map.Entry<String, ResourceInformation> entry : resourceTypes for (ResourceInformation entry : resourceTypesArray) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey();
if (name.equals(ResourceInformation.MEMORY_MB.getName())) { if (name.equals(ResourceInformation.MEMORY_MB.getName())) {
ret.setMemorySize(entry.getValue().getMinimumAllocation()); ret.setMemorySize(entry.getMinimumAllocation());
continue; } else if (name.equals(ResourceInformation.VCORES.getName())) {
} Long tmp = entry.getMinimumAllocation();
if (name.equals(ResourceInformation.VCORES.getName())) {
Long tmp = entry.getValue().getMinimumAllocation();
if (tmp > Integer.MAX_VALUE) { if (tmp > Integer.MAX_VALUE) {
tmp = (long) Integer.MAX_VALUE; tmp = (long) Integer.MAX_VALUE;
} }
ret.setVirtualCores(tmp.intValue()); ret.setVirtualCores(tmp.intValue());
continue; } else {
ret.setResourceValue(name, entry.getMinimumAllocation());
} }
ret.setResourceValue(name, entry.getValue().getMinimumAllocation());
} }
return ret; return ret;
} }
@ -464,24 +513,21 @@ public class ResourceUtils {
* @return a Resource object with the maximum allocation for the scheduler * @return a Resource object with the maximum allocation for the scheduler
*/ */
public static Resource getResourceTypesMaximumAllocation() { public static Resource getResourceTypesMaximumAllocation() {
Map<String, ResourceInformation> resourceTypes = getResourceTypes();
Resource ret = Resource.newInstance(0, 0); Resource ret = Resource.newInstance(0, 0);
for (Map.Entry<String, ResourceInformation> entry : resourceTypes for (ResourceInformation entry : resourceTypesArray) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey();
if (name.equals(ResourceInformation.MEMORY_MB.getName())) { if (name.equals(ResourceInformation.MEMORY_MB.getName())) {
ret.setMemorySize(entry.getValue().getMaximumAllocation()); ret.setMemorySize(entry.getMaximumAllocation());
continue; } else if (name.equals(ResourceInformation.VCORES.getName())) {
} Long tmp = entry.getMaximumAllocation();
if (name.equals(ResourceInformation.VCORES.getName())) {
Long tmp = entry.getValue().getMaximumAllocation();
if (tmp > Integer.MAX_VALUE) { if (tmp > Integer.MAX_VALUE) {
tmp = (long) Integer.MAX_VALUE; tmp = (long) Integer.MAX_VALUE;
} }
ret.setVirtualCores(tmp.intValue()); ret.setVirtualCores(tmp.intValue());
continue; continue;
} else {
ret.setResourceValue(name, entry.getMaximumAllocation());
} }
ret.setResourceValue(name, entry.getValue().getMaximumAllocation());
} }
return ret; return ret;
} }

View File

@ -0,0 +1,22 @@
/*
* 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.
*/
@InterfaceAudience.Public
@InterfaceStability.Unstable
package org.apache.hadoop.yarn.util.resource;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

View File

@ -472,9 +472,8 @@ public class ProtoUtils {
List<YarnProtos.StringLongMapProto> pList) { List<YarnProtos.StringLongMapProto> pList) {
Resource tmp = Resource.newInstance(0, 0); Resource tmp = Resource.newInstance(0, 0);
Map<String, Long> ret = new HashMap<>(); Map<String, Long> ret = new HashMap<>();
for (Map.Entry<String, ResourceInformation> entry : tmp.getResources() for (ResourceInformation entry : tmp.getResources()) {
.entrySet()) { ret.put(entry.getName(), 0L);
ret.put(entry.getKey(), 0L);
} }
if (pList != null) { if (pList != null) {
for (YarnProtos.StringLongMapProto p : pList) { for (YarnProtos.StringLongMapProto p : pList) {

View File

@ -25,6 +25,7 @@ import org.apache.hadoop.classification.InterfaceStability.Unstable;
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.impl.BaseResource;
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException; import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
import org.apache.hadoop.yarn.proto.YarnProtos.ResourceProto; import org.apache.hadoop.yarn.proto.YarnProtos.ResourceProto;
@ -33,14 +34,13 @@ import org.apache.hadoop.yarn.proto.YarnProtos.ResourceInformationProto;
import org.apache.hadoop.yarn.util.resource.ResourceUtils; import org.apache.hadoop.yarn.util.resource.ResourceUtils;
import org.apache.hadoop.yarn.util.UnitsConversionUtil; import org.apache.hadoop.yarn.util.UnitsConversionUtil;
import java.util.HashMap; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Collections;
@Private @Private
@Unstable @Unstable
public class ResourcePBImpl extends Resource { public class ResourcePBImpl extends BaseResource {
private static final Log LOG = LogFactory.getLog(ResourcePBImpl.class); private static final Log LOG = LogFactory.getLog(ResourcePBImpl.class);
@ -48,10 +48,6 @@ public class ResourcePBImpl extends Resource {
ResourceProto.Builder builder = null; ResourceProto.Builder builder = null;
boolean viaProto = false; boolean viaProto = false;
private Map<String, ResourceInformation> resources;
private Map<String, ResourceInformation> readOnlyResources;
// call via ProtoUtils.convertToProtoFormat(Resource) // call via ProtoUtils.convertToProtoFormat(Resource)
static ResourceProto getProto(Resource r) { static ResourceProto getProto(Resource r) {
final ResourcePBImpl pb; final ResourcePBImpl pb;
@ -72,8 +68,6 @@ public class ResourcePBImpl extends Resource {
public ResourcePBImpl(ResourceProto proto) { public ResourcePBImpl(ResourceProto proto) {
this.proto = proto; this.proto = proto;
viaProto = true; viaProto = true;
this.readOnlyResources = null;
this.resources = null;
initResources(); initResources();
} }
@ -101,11 +95,13 @@ public class ResourcePBImpl extends Resource {
public long getMemorySize() { public long getMemorySize() {
// memory should always be present // memory should always be present
initResources(); initResources();
ResourceInformation ri = ResourceInformation ri = resources[MandatoryResources.MEMORY.getId()];
this.getResourceInformation(ResourceInformation.MEMORY_MB.getName());
return UnitsConversionUtil if (ri.getUnits().isEmpty()) {
.convert(ri.getUnits(), ResourceInformation.MEMORY_MB.getUnits(), return ri.getValue();
ri.getValue()); }
return UnitsConversionUtil.convert(ri.getUnits(),
ResourceInformation.MEMORY_MB.getUnits(), ri.getValue());
} }
@Override @Override
@ -117,23 +113,20 @@ public class ResourcePBImpl extends Resource {
@Override @Override
public void setMemorySize(long memory) { public void setMemorySize(long memory) {
maybeInitBuilder(); maybeInitBuilder();
getResourceInformation(ResourceInformation.MEMORY_MB.getName()) getResourceInformation(MEMORY).setValue(memory);
.setValue(memory);
} }
@Override @Override
public int getVirtualCores() { public int getVirtualCores() {
// vcores should always be present // vcores should always be present
initResources(); initResources();
return this.getResourceValue(ResourceInformation.VCORES.getName()) return (int) resources[MandatoryResources.VCORES.getId()].getValue();
.intValue();
} }
@Override @Override
public void setVirtualCores(int vCores) { public void setVirtualCores(int vCores) {
maybeInitBuilder(); maybeInitBuilder();
getResourceInformation(ResourceInformation.VCORES.getName()) getResourceInformation(VCORES).setValue(vCores);
.setValue(vCores);
} }
private void initResources() { private void initResources() {
@ -142,6 +135,7 @@ public class ResourcePBImpl extends Resource {
} }
ResourceProtoOrBuilder p = viaProto ? proto : builder; ResourceProtoOrBuilder p = viaProto ? proto : builder;
initResourcesMap(); initResourcesMap();
Map<String, Integer> indexMap = ResourceUtils.getResourceTypeIndex();
for (ResourceInformationProto entry : p.getResourceValueMapList()) { for (ResourceInformationProto entry : p.getResourceValueMapList()) {
ResourceTypes type = ResourceTypes type =
entry.hasType() ? ProtoUtils.convertFromProtoFormat(entry.getType()) : entry.hasType() ? ProtoUtils.convertFromProtoFormat(entry.getType()) :
@ -150,14 +144,16 @@ public class ResourcePBImpl extends Resource {
long value = entry.hasValue() ? entry.getValue() : 0L; long value = entry.hasValue() ? entry.getValue() : 0L;
ResourceInformation ri = ResourceInformation ResourceInformation ri = ResourceInformation
.newInstance(entry.getKey(), units, value, type, 0L, Long.MAX_VALUE); .newInstance(entry.getKey(), units, value, type, 0L, Long.MAX_VALUE);
if (resources.containsKey(ri.getName())) { Integer index = indexMap.get(entry.getKey());
resources.get(ri.getName()).setResourceType(ri.getResourceType()); if (index == null) {
resources.get(ri.getName()).setUnits(ri.getUnits());
resources.get(ri.getName()).setValue(value);
} else {
LOG.warn("Got unknown resource type: " + ri.getName() + "; skipping"); LOG.warn("Got unknown resource type: " + ri.getName() + "; skipping");
} else {
resources[index].setResourceType(ri.getResourceType());
resources[index].setUnits(ri.getUnits());
resources[index].setValue(value);
} }
} }
readOnlyResources = Arrays.copyOf(resources, resources.length);
this.setMemorySize(p.getMemory()); this.setMemorySize(p.getMemory());
this.setVirtualCores(p.getVirtualCores()); this.setVirtualCores(p.getVirtualCores());
} }
@ -173,79 +169,67 @@ public class ResourcePBImpl extends Resource {
if (!resource.equals(resourceInformation.getName())) { if (!resource.equals(resourceInformation.getName())) {
resourceInformation.setName(resource); resourceInformation.setName(resource);
} }
initResources(); ResourceInformation storedResourceInfo = getResourceInformation(resource);
if (resources.containsKey(resource)) { ResourceInformation.copy(resourceInformation, storedResourceInfo);
ResourceInformation.copy(resourceInformation, resources.get(resource));
}
} }
@Override @Override
public void setResourceValue(String resource, Long value) public void setResourceValue(String resource, Long value)
throws ResourceNotFoundException { throws ResourceNotFoundException {
maybeInitBuilder(); maybeInitBuilder();
initResources();
if (resource == null) { if (resource == null) {
throw new IllegalArgumentException("resource type object cannot be null"); throw new IllegalArgumentException("resource type object cannot be null");
} }
if (resources == null || (!resources.containsKey(resource))) { getResourceInformation(resource).setValue(value);
throw new ResourceNotFoundException(
"Resource " + resource + " not found");
}
resources.get(resource).setValue(value);
} }
@Override @Override
public Map<String, ResourceInformation> getResources() { public ResourceInformation[] getResources() {
initResources(); initResources();
return readOnlyResources; return super.getResources();
} }
@Override @Override
public ResourceInformation getResourceInformation(String resource) { public ResourceInformation getResourceInformation(String resource)
throws ResourceNotFoundException {
initResources(); initResources();
if (this.resources.containsKey(resource)) { return super.getResourceInformation(resource);
return this.resources.get(resource);
}
throw new ResourceNotFoundException("Could not find entry for " + resource);
} }
@Override @Override
public Long getResourceValue(String resource) { public long getResourceValue(String resource)
throws ResourceNotFoundException {
initResources(); initResources();
if (this.resources.containsKey(resource)) { return super.getResourceValue(resource);
return this.resources.get(resource).getValue();
}
throw new ResourceNotFoundException("Could not find entry for " + resource);
} }
private void initResourcesMap() { private void initResourcesMap() {
if (resources == null) { if (resources == null) {
resources = new HashMap<>(); ResourceInformation[] types = ResourceUtils.getResourceTypesArray();
Map<String, ResourceInformation> types = ResourceUtils.getResourceTypes();
if (types == null) { if (types == null) {
throw new YarnRuntimeException( throw new YarnRuntimeException(
"Got null return value from ResourceUtils.getResourceTypes()"); "Got null return value from ResourceUtils.getResourceTypes()");
} }
for (Map.Entry<String, ResourceInformation> entry : types.entrySet()) {
resources.put(entry.getKey(), resources = new ResourceInformation[types.length];
ResourceInformation.newInstance(entry.getValue())); readOnlyResources = new ResourceInformation[types.length];
for (ResourceInformation entry : types) {
int index = ResourceUtils.getResourceTypeIndex().get(entry.getName());
resources[index] = ResourceInformation.newInstance(entry);
} }
readOnlyResources = Collections.unmodifiableMap(resources);
} }
} }
synchronized private void mergeLocalToBuilder() { synchronized private void mergeLocalToBuilder() {
builder.clearResourceValueMap(); builder.clearResourceValueMap();
if (resources != null && !resources.isEmpty()) { if(resources != null && resources.length != 0) {
for (Map.Entry<String, ResourceInformation> entry : for (ResourceInformation resInfo : resources) {
resources.entrySet()) { ResourceInformationProto.Builder e = ResourceInformationProto
ResourceInformationProto.Builder e = .newBuilder();
ResourceInformationProto.newBuilder(); e.setKey(resInfo.getName());
e.setKey(entry.getKey()); e.setUnits(resInfo.getUnits());
e.setUnits(entry.getValue().getUnits()); e.setType(ProtoUtils.converToProtoFormat(resInfo.getResourceType()));
e.setType( e.setValue(resInfo.getValue());
ProtoUtils.converToProtoFormat(entry.getValue().getResourceType()));
e.setValue(entry.getValue().getValue());
builder.addResourceValueMap(e); builder.addResourceValueMap(e);
} }
} }

View File

@ -23,10 +23,9 @@ 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.exceptions.YarnException; import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
import org.apache.hadoop.yarn.util.UnitsConversionUtil; import org.apache.hadoop.yarn.util.UnitsConversionUtil;
import java.util.Set;
/** /**
* A {@link ResourceCalculator} which uses the concept of * A {@link ResourceCalculator} which uses the concept of
@ -56,10 +55,10 @@ public class DominantResourceCalculator extends ResourceCalculator {
LogFactory.getLog(DominantResourceCalculator.class); LogFactory.getLog(DominantResourceCalculator.class);
private Set<String> resourceNames; private String[] resourceNames;
public DominantResourceCalculator() { public DominantResourceCalculator() {
resourceNames = ResourceUtils.getResourceTypes().keySet(); resourceNames = ResourceUtils.getResourceNamesArray();
} }
/** /**
@ -88,7 +87,7 @@ public class DominantResourceCalculator extends ResourceCalculator {
} else if (diff <= -1) { } else if (diff <= -1) {
rhsGreater = true; rhsGreater = true;
} }
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Error getting resource information for " + rName, ye); "Error getting resource information for " + rName, ye);
} }
@ -163,7 +162,7 @@ public class DominantResourceCalculator extends ResourceCalculator {
.getValue(); .getValue();
min = min < tmp ? min : tmp; min = min < tmp ? min : tmp;
max = max > tmp ? max : tmp; max = max > tmp ? max : tmp;
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Error getting resource information for " + resource, ye); "Error getting resource information for " + resource, ye);
} }
@ -187,7 +186,7 @@ public class DominantResourceCalculator extends ResourceCalculator {
long tmp = availableResource.getValue() / requiredResourceValue; long tmp = availableResource.getValue() / requiredResourceValue;
min = min < tmp ? min : tmp; min = min < tmp ? min : tmp;
} }
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Error getting resource information for " + resource, ye); "Error getting resource information for " + resource, ye);
} }
@ -206,15 +205,10 @@ public class DominantResourceCalculator extends ResourceCalculator {
@Override @Override
public boolean isInvalidDivisor(Resource r) { public boolean isInvalidDivisor(Resource r) {
for (String resource : resourceNames) { for (ResourceInformation res : r.getResources()) {
try { if (res.getValue() == 0L) {
if (r.getResourceValue(resource).equals(0L)) {
return true; return true;
} }
} catch (YarnException ye) {
throw new IllegalArgumentException(
"Error getting resource value for " + resource, ye);
}
} }
return false; return false;
} }
@ -235,7 +229,7 @@ public class DominantResourceCalculator extends ResourceCalculator {
float tmp = float tmp =
(float) aResourceInformation.getValue() / (float) bResourceValue; (float) aResourceInformation.getValue() / (float) bResourceValue;
ratio = ratio > tmp ? ratio : tmp; ratio = ratio > tmp ? ratio : tmp;
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Error getting resource information for " + resource, ye); "Error getting resource information for " + resource, ye);
} }
@ -256,7 +250,7 @@ public class DominantResourceCalculator extends ResourceCalculator {
ret.getResourceInformation(resource); ret.getResourceInformation(resource);
resourceInformation.setValue( resourceInformation.setValue(
divideAndCeil(resourceInformation.getValue(), denominator)); divideAndCeil(resourceInformation.getValue(), denominator));
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Error getting resource information for " + resource, ye); "Error getting resource information for " + resource, ye);
} }
@ -307,7 +301,7 @@ public class DominantResourceCalculator extends ResourceCalculator {
} }
tmp.setValue(Math.min(value, maximumValue)); tmp.setValue(Math.min(value, maximumValue));
ret.setResourceInformation(resource, tmp); ret.setResourceInformation(resource, tmp);
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Error getting resource information for " + resource, ye); "Error getting resource information for " + resource, ye);
} }
@ -347,7 +341,7 @@ public class DominantResourceCalculator extends ResourceCalculator {
ResourceInformation ResourceInformation
.copy(rResourceInformation, ret.getResourceInformation(resource)); .copy(rResourceInformation, ret.getResourceInformation(resource));
ret.getResourceInformation(resource).setValue(value); ret.getResourceInformation(resource).setValue(value);
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Error getting resource information for " + resource, ye); "Error getting resource information for " + resource, ye);
} }
@ -372,28 +366,29 @@ public class DominantResourceCalculator extends ResourceCalculator {
Resource ret = Resource.newInstance(r); Resource ret = Resource.newInstance(r);
for (String resource : resourceNames) { for (String resource : resourceNames) {
try { try {
ResourceInformation rResourceInformation = ResourceInformation rResourceInformation = r
r.getResourceInformation(resource); .getResourceInformation(resource);
ResourceInformation stepFactorResourceInformation = ResourceInformation stepFactorResourceInformation = stepFactor
stepFactor.getResourceInformation(resource); .getResourceInformation(resource);
ResourceInformation tmp = ret.getResourceInformation(resource); ResourceInformation tmp = ret.getResourceInformation(resource);
Long rValue = rResourceInformation.getValue(); long rValue = rResourceInformation.getValue();
Long stepFactorValue = UnitsConversionUtil long stepFactorValue = UnitsConversionUtil.convert(
.convert(stepFactorResourceInformation.getUnits(), stepFactorResourceInformation.getUnits(),
rResourceInformation.getUnits(), rResourceInformation.getUnits(),
stepFactorResourceInformation.getValue()); stepFactorResourceInformation.getValue());
Long value; long value;
if (stepFactorValue != 0) { if (stepFactorValue != 0) {
value = roundUp ? value = roundUp
roundUp((long) Math.ceil(rValue * by), stepFactorValue) : ? roundUp((long) Math.ceil(rValue * by), stepFactorValue)
roundDown((long) (rValue * by), stepFactorValue); : roundDown((long) (rValue * by), stepFactorValue);
} else { } else {
value = value = roundUp
roundUp ? (long) Math.ceil(rValue * by) : (long) (rValue * by); ? (long) Math.ceil(rValue * by)
: (long) (rValue * by);
} }
tmp.setValue(value); tmp.setValue(value);
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Error getting resource information for " + resource, ye); "Error getting resource information for " + resource, ye);
} }
@ -416,7 +411,7 @@ public class DominantResourceCalculator extends ResourceCalculator {
if(sResourceValue > bResourceInformation.getValue()) { if(sResourceValue > bResourceInformation.getValue()) {
return false; return false;
} }
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
return false; return false;
} }
} }

View File

@ -18,30 +18,31 @@
package org.apache.hadoop.yarn.util.resource; package org.apache.hadoop.yarn.util.resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
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.BaseResource;
import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException; import org.apache.hadoop.yarn.exceptions.ResourceNotFoundException;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.util.Records;
import org.apache.hadoop.yarn.util.UnitsConversionUtil; import org.apache.hadoop.yarn.util.UnitsConversionUtil;
import java.util.Collections; import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@InterfaceAudience.LimitedPrivate({ "YARN", "MapReduce" }) @InterfaceAudience.LimitedPrivate({ "YARN", "MapReduce" })
@Unstable @Unstable
public class Resources { public class Resources {
private static final Log LOG =
LogFactory.getLog(Resources.class);
/** /**
* 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.
*/ */
static class FixedValueResource extends Resource { static class FixedValueResource extends BaseResource {
private Map<String, ResourceInformation> resources;
private long resourceValue; private long resourceValue;
private String name; private String name;
@ -53,7 +54,7 @@ public class Resources {
FixedValueResource(String rName, long value) { FixedValueResource(String rName, long value) {
this.resourceValue = value; this.resourceValue = value;
this.name = rName; this.name = rName;
resources = initResourceMap(); initResourceMap();
} }
private int resourceValueToInt() { private int resourceValueToInt() {
@ -95,31 +96,6 @@ public class Resources {
throw new RuntimeException(name + " cannot be modified!"); throw new RuntimeException(name + " cannot be modified!");
} }
@Override
public Map<String, ResourceInformation> getResources() {
return Collections.unmodifiableMap(this.resources);
}
@Override
public ResourceInformation getResourceInformation(String resource)
throws YarnException {
if (resources.containsKey(resource)) {
ResourceInformation value = this.resources.get(resource);
ResourceInformation ret = ResourceInformation.newInstance(value);
ret.setValue(resourceValue);
return ret;
}
throw new YarnException("" + resource + " not found");
}
@Override
public Long getResourceValue(String resource) throws YarnException {
if (resources.containsKey(resource)) {
return resourceValue;
}
throw new YarnException("" + resource + " not found");
}
@Override @Override
public void setResourceInformation(String resource, public void setResourceInformation(String resource,
ResourceInformation resourceInformation) ResourceInformation resourceInformation)
@ -133,24 +109,24 @@ public class Resources {
throw new RuntimeException(name + " cannot be modified!"); throw new RuntimeException(name + " cannot be modified!");
} }
private Map<String, ResourceInformation> initResourceMap() { private void initResourceMap() {
Map<String, ResourceInformation> tmp = new HashMap<>(); ResourceInformation[] types = ResourceUtils.getResourceTypesArray();
Map<String, ResourceInformation> types = ResourceUtils.getResourceTypes();
if (types != null) { if (types != null) {
for (Map.Entry<String, ResourceInformation> entry : types.entrySet()) { resources = new ResourceInformation[types.length];
tmp.put(entry.getKey(), readOnlyResources = new ResourceInformation[types.length];
ResourceInformation.newInstance(entry.getValue())); for (int index = 0; index < types.length; index++) {
tmp.get(entry.getKey()).setValue(resourceValue); resources[index] = ResourceInformation.newInstance(types[index]);
} resources[index].setValue(resourceValue);
}
// this is a fix for getVirtualCores returning an int
if (resourceValue > Integer.MAX_VALUE) {
tmp.get(ResourceInformation.VCORES.getName())
.setValue((long) Integer.MAX_VALUE);
}
return tmp;
}
// this is a fix for getVirtualCores returning an int
if (resourceValue > Integer.MAX_VALUE && ResourceInformation.VCORES
.getName().equals(resources[index].getName())) {
resources[index].setValue((long) Integer.MAX_VALUE);
}
}
}
readOnlyResources = Arrays.copyOf(resources, resources.length);
}
} }
public static Resource createResource(int memory) { public static Resource createResource(int memory) {
@ -197,17 +173,19 @@ public class Resources {
} }
public static Resource addTo(Resource lhs, Resource rhs) { public static Resource addTo(Resource lhs, Resource rhs) {
for (Map.Entry<String, ResourceInformation> entry : lhs.getResources() for (ResourceInformation entry : lhs.getResources()) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey();
try { try {
ResourceInformation rhsValue = rhs.getResourceInformation(name); ResourceInformation rhsValue = rhs.getResourceInformation(name);
ResourceInformation lhsValue = entry.getValue(); ResourceInformation lhsValue = entry;
long convertedRhs = UnitsConversionUtil
.convert(rhsValue.getUnits(), lhsValue.getUnits(), long convertedRhs = (rhsValue.getUnits().equals(lhsValue.getUnits()))
rhsValue.getValue()); ? rhsValue.getValue()
: UnitsConversionUtil.convert(rhsValue.getUnits(),
lhsValue.getUnits(), rhsValue.getValue());
lhs.setResourceValue(name, lhsValue.getValue() + convertedRhs); lhs.setResourceValue(name, lhsValue.getValue() + convertedRhs);
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
LOG.warn("Resource is missing:" + ye.getMessage());
continue; continue;
} }
} }
@ -219,17 +197,19 @@ public class Resources {
} }
public static Resource subtractFrom(Resource lhs, Resource rhs) { public static Resource subtractFrom(Resource lhs, Resource rhs) {
for (Map.Entry<String, ResourceInformation> entry : lhs.getResources() for (ResourceInformation entry : lhs.getResources()) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey();
try { try {
ResourceInformation rhsValue = rhs.getResourceInformation(name); ResourceInformation rhsValue = rhs.getResourceInformation(name);
ResourceInformation lhsValue = entry.getValue(); ResourceInformation lhsValue = entry;
long convertedRhs = UnitsConversionUtil
.convert(rhsValue.getUnits(), lhsValue.getUnits(), long convertedRhs = (rhsValue.getUnits().equals(lhsValue.getUnits()))
rhsValue.getValue()); ? rhsValue.getValue()
: UnitsConversionUtil.convert(rhsValue.getUnits(),
lhsValue.getUnits(), rhsValue.getValue());
lhs.setResourceValue(name, lhsValue.getValue() - convertedRhs); lhs.setResourceValue(name, lhsValue.getValue() - convertedRhs);
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
LOG.warn("Resource is missing:" + ye.getMessage());
continue; continue;
} }
} }
@ -263,10 +243,9 @@ public class Resources {
} }
public static Resource multiplyTo(Resource lhs, double by) { public static Resource multiplyTo(Resource lhs, double by) {
for (Map.Entry<String, ResourceInformation> entry : lhs.getResources() for (ResourceInformation entry : lhs.getResources()) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey(); ResourceInformation lhsValue = entry;
ResourceInformation lhsValue = entry.getValue();
lhs.setResourceValue(name, (long) (lhsValue.getValue() * by)); lhs.setResourceValue(name, (long) (lhsValue.getValue() * by));
} }
return lhs; return lhs;
@ -282,17 +261,21 @@ public class Resources {
*/ */
public static Resource multiplyAndAddTo( public static Resource multiplyAndAddTo(
Resource lhs, Resource rhs, double by) { Resource lhs, Resource rhs, double by) {
for (Map.Entry<String, ResourceInformation> entry : lhs.getResources() for (ResourceInformation entry : lhs.getResources()) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey();
try { try {
ResourceInformation rhsValue = rhs.getResourceInformation(name); ResourceInformation rhsValue = rhs.getResourceInformation(name);
ResourceInformation lhsValue = entry.getValue(); ResourceInformation lhsValue = entry;
long convertedRhs = (long) (UnitsConversionUtil
.convert(rhsValue.getUnits(), lhsValue.getUnits(), long convertedRhs = (long) (((rhsValue.getUnits()
rhsValue.getValue()) * by); .equals(lhsValue.getUnits()))
? rhsValue.getValue()
: UnitsConversionUtil.convert(rhsValue.getUnits(),
lhsValue.getUnits(), rhsValue.getValue()))
* by);
lhs.setResourceValue(name, lhsValue.getValue() + convertedRhs); lhs.setResourceValue(name, lhsValue.getValue() + convertedRhs);
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
LOG.warn("Resource is missing:" + ye.getMessage());
continue; continue;
} }
} }
@ -311,10 +294,9 @@ public class Resources {
public static Resource multiplyAndRoundDown(Resource lhs, double by) { public static Resource multiplyAndRoundDown(Resource lhs, double by) {
Resource out = clone(lhs); Resource out = clone(lhs);
for (Map.Entry<String, ResourceInformation> entry : out.getResources() for (ResourceInformation entry : out.getResources()) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey(); ResourceInformation lhsValue = entry;
ResourceInformation lhsValue = entry.getValue();
out.setResourceValue(name, (long) (lhsValue.getValue() * by)); out.setResourceValue(name, (long) (lhsValue.getValue() * by));
} }
return out; return out;
@ -416,19 +398,21 @@ public class Resources {
} }
public static boolean fitsIn(Resource smaller, Resource bigger) { public static boolean fitsIn(Resource smaller, Resource bigger) {
for (Map.Entry<String, ResourceInformation> entry : smaller.getResources() for (ResourceInformation entry : smaller.getResources()) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey();
try { try {
ResourceInformation rhsValue = bigger.getResourceInformation(name); ResourceInformation rhsValue = bigger.getResourceInformation(name);
ResourceInformation lhsValue = entry.getValue(); ResourceInformation lhsValue = entry;
long convertedRhs = UnitsConversionUtil
.convert(rhsValue.getUnits(), lhsValue.getUnits(), long convertedRhs = (rhsValue.getUnits().equals(lhsValue.getUnits()))
rhsValue.getValue()); ? rhsValue.getValue()
: UnitsConversionUtil.convert(rhsValue.getUnits(),
lhsValue.getUnits(), rhsValue.getValue());
if(lhsValue.getValue() > convertedRhs) { if(lhsValue.getValue() > convertedRhs) {
return false; return false;
} }
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
LOG.warn("Resource is missing:" + ye.getMessage());
return false; return false;
} }
} }
@ -442,19 +426,21 @@ public class Resources {
public static Resource componentwiseMin(Resource lhs, Resource rhs) { public static Resource componentwiseMin(Resource lhs, Resource rhs) {
Resource ret = createResource(0); Resource ret = createResource(0);
for (Map.Entry<String, ResourceInformation> entry : lhs.getResources() for (ResourceInformation entry : lhs.getResources()) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey();
try { try {
ResourceInformation rhsValue = rhs.getResourceInformation(name); ResourceInformation rhsValue = rhs.getResourceInformation(name);
ResourceInformation lhsValue = entry.getValue(); ResourceInformation lhsValue = entry;
long convertedRhs = UnitsConversionUtil
.convert(rhsValue.getUnits(), lhsValue.getUnits(), long convertedRhs = (rhsValue.getUnits().equals(lhsValue.getUnits()))
rhsValue.getValue()); ? rhsValue.getValue()
: UnitsConversionUtil.convert(rhsValue.getUnits(),
lhsValue.getUnits(), rhsValue.getValue());
ResourceInformation outInfo = ResourceInformation outInfo =
lhsValue.getValue() < convertedRhs ? lhsValue : rhsValue; lhsValue.getValue() < convertedRhs ? lhsValue : rhsValue;
ret.setResourceInformation(name, outInfo); ret.setResourceInformation(name, outInfo);
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
LOG.warn("Resource is missing:" + ye.getMessage());
continue; continue;
} }
} }
@ -463,19 +449,21 @@ public class Resources {
public static Resource componentwiseMax(Resource lhs, Resource rhs) { public static Resource componentwiseMax(Resource lhs, Resource rhs) {
Resource ret = createResource(0); Resource ret = createResource(0);
for (Map.Entry<String, ResourceInformation> entry : lhs.getResources() for (ResourceInformation entry : lhs.getResources()) {
.entrySet()) { String name = entry.getName();
String name = entry.getKey();
try { try {
ResourceInformation rhsValue = rhs.getResourceInformation(name); ResourceInformation rhsValue = rhs.getResourceInformation(name);
ResourceInformation lhsValue = entry.getValue(); ResourceInformation lhsValue = entry;
long convertedRhs = UnitsConversionUtil
.convert(rhsValue.getUnits(), lhsValue.getUnits(), long convertedRhs = (rhsValue.getUnits().equals(lhsValue.getUnits()))
rhsValue.getValue()); ? rhsValue.getValue()
: UnitsConversionUtil.convert(rhsValue.getUnits(),
lhsValue.getUnits(), rhsValue.getValue());
ResourceInformation outInfo = ResourceInformation outInfo =
lhsValue.getValue() > convertedRhs ? lhsValue : rhsValue; lhsValue.getValue() > convertedRhs ? lhsValue : rhsValue;
ret.setResourceInformation(name, outInfo); ret.setResourceInformation(name, outInfo);
} catch (YarnException ye) { } catch (ResourceNotFoundException ye) {
LOG.warn("Resource is missing:" + ye.getMessage());
continue; continue;
} }
} }

View File

@ -276,13 +276,17 @@ public class TestResourceUtils {
String resourceFile = entry.getKey(); String resourceFile = entry.getKey();
ResourceUtils.resetNodeResources(); ResourceUtils.resetNodeResources();
File dest; File dest;
File source = File source = new File(
new File(conf.getClassLoader().getResource(resourceFile).getFile()); conf.getClassLoader().getResource(resourceFile).getFile());
dest = new File(source.getParent(), "node-resources.xml"); dest = new File(source.getParent(), "node-resources.xml");
FileUtils.copyFile(source, dest); FileUtils.copyFile(source, dest);
Map<String, ResourceInformation> actual = Map<String, ResourceInformation> actual = ResourceUtils
ResourceUtils.getNodeResourceInformation(conf); .getNodeResourceInformation(conf);
Assert.assertEquals(entry.getValue().getResources(), actual); Assert.assertEquals(actual.size(),
entry.getValue().getResources().length);
for (ResourceInformation resInfo : entry.getValue().getResources()) {
Assert.assertEquals(resInfo, actual.get(resInfo.getName()));
}
dest.delete(); dest.delete();
} }
} }

View File

@ -105,7 +105,7 @@ public class TestResources {
unboundedClone.compareTo(createResource(0, Integer.MAX_VALUE)) > 0); unboundedClone.compareTo(createResource(0, Integer.MAX_VALUE)) > 0);
} }
@Test(timeout=10000) @Test(timeout = 10000)
public void testCompareToWithNoneResource() { public void testCompareToWithNoneResource() {
assertTrue(Resources.none().compareTo(createResource(0, 0)) == 0); assertTrue(Resources.none().compareTo(createResource(0, 0)) == 0);
assertTrue(Resources.none().compareTo(createResource(1, 0)) < 0); assertTrue(Resources.none().compareTo(createResource(1, 0)) < 0);
@ -114,7 +114,6 @@ public class TestResources {
assertTrue(Resources.none().compareTo(createResource(1, 0, 0)) < 0); assertTrue(Resources.none().compareTo(createResource(1, 0, 0)) < 0);
assertTrue(Resources.none().compareTo(createResource(0, 1, 0)) < 0); assertTrue(Resources.none().compareTo(createResource(0, 1, 0)) < 0);
assertTrue(Resources.none().compareTo(createResource(0, 0, 1)) < 0); assertTrue(Resources.none().compareTo(createResource(0, 0, 1)) < 0);
assertTrue(Resources.none().compareTo(createResource(0, 0, 1)) < 0);
} }
@Test(timeout=10000) @Test(timeout=10000)
@ -246,7 +245,9 @@ public class TestResources {
} }
@Test @Test
public void testMultiplyAndAddTo() { public void testMultiplyAndAddTo() throws Exception {
unsetExtraResourceType();
setupExtraResourceType();
assertEquals(createResource(6, 4), assertEquals(createResource(6, 4),
multiplyAndAddTo(createResource(3, 1), createResource(2, 2), 1.5)); multiplyAndAddTo(createResource(3, 1), createResource(2, 2), 1.5));
assertEquals(createResource(6, 4, 0), assertEquals(createResource(6, 4, 0),

View File

@ -178,16 +178,15 @@ public class RMAppAttemptMetrics {
private void updateUsageMap(Resource allocated, long deltaUsedMillis, private void updateUsageMap(Resource allocated, long deltaUsedMillis,
Map<String, AtomicLong> targetMap) { Map<String, AtomicLong> targetMap) {
for (Map.Entry<String, ResourceInformation> entry : allocated.getResources() for (ResourceInformation entry : allocated.getResources()) {
.entrySet()) {
AtomicLong resourceUsed; AtomicLong resourceUsed;
if (!targetMap.containsKey(entry.getKey())) { if (!targetMap.containsKey(entry.getName())) {
resourceUsed = new AtomicLong(0); resourceUsed = new AtomicLong(0);
targetMap.put(entry.getKey(), resourceUsed); targetMap.put(entry.getName(), resourceUsed);
} }
resourceUsed = targetMap.get(entry.getKey()); resourceUsed = targetMap.get(entry.getName());
resourceUsed.addAndGet((entry.getValue().getValue() * deltaUsedMillis) resourceUsed.addAndGet((entry.getValue() * deltaUsedMillis)
/ DateUtils.MILLIS_PER_SECOND); / DateUtils.MILLIS_PER_SECOND);
} }
} }

View File

@ -1006,13 +1006,12 @@ public class SchedulerApplicationAttempt implements SchedulableEntity {
for (RMContainer rmContainer : this.liveContainers.values()) { for (RMContainer rmContainer : this.liveContainers.values()) {
long usedMillis = currentTimeMillis - rmContainer.getCreationTime(); long usedMillis = currentTimeMillis - rmContainer.getCreationTime();
Resource resource = rmContainer.getContainer().getResource(); Resource resource = rmContainer.getContainer().getResource();
for (Map.Entry<String, ResourceInformation> entry : resource for (ResourceInformation entry : resource.getResources()) {
.getResources().entrySet()) {
long value = RMServerUtils long value = RMServerUtils
.getOrDefault(resourceSecondsMap, entry.getKey(), 0L); .getOrDefault(resourceSecondsMap, entry.getName(), 0L);
value += entry.getValue().getValue() * usedMillis value += entry.getValue() * usedMillis
/ DateUtils.MILLIS_PER_SECOND; / DateUtils.MILLIS_PER_SECOND;
resourceSecondsMap.put(entry.getKey(), value); resourceSecondsMap.put(entry.getName(), value);
} }
} }

View File

@ -18,6 +18,7 @@
package org.apache.hadoop.yarn.server.resourcemanager.webapp.dao; package org.apache.hadoop.yarn.server.resourcemanager.webapp.dao;
import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
@ -73,7 +74,7 @@ public class SchedulerInfo {
} }
public String getSchedulerResourceTypes() { public String getSchedulerResourceTypes() {
return minAllocResource.getResource().getResources().keySet().toString(); return Arrays.toString(minAllocResource.getResource().getResources());
} }
public int getMaxClusterLevelAppPriority() { public int getMaxClusterLevelAppPriority() {

View File

@ -249,6 +249,7 @@ public class TestAppManager{
ResourceScheduler scheduler = mockResourceScheduler(); ResourceScheduler scheduler = mockResourceScheduler();
((RMContextImpl)rmContext).setScheduler(scheduler); ((RMContextImpl)rmContext).setScheduler(scheduler);
Configuration conf = new Configuration(); Configuration conf = new Configuration();
conf.setBoolean(YarnConfiguration.NODE_LABELS_ENABLED, true);
((RMContextImpl) rmContext).setYarnConfiguration(conf); ((RMContextImpl) rmContext).setYarnConfiguration(conf);
ApplicationMasterService masterService = ApplicationMasterService masterService =
new ApplicationMasterService(rmContext, scheduler); new ApplicationMasterService(rmContext, scheduler);