[FLINK-7928] Move Resource out of ResourceSpec

上级 5643d156
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
package org.apache.flink.api.common.operators; package org.apache.flink.api.common.operators;
import org.apache.flink.annotation.Internal; import org.apache.flink.annotation.Internal;
import org.apache.flink.util.Preconditions; import org.apache.flink.api.common.resources.GPUResource;
import org.apache.flink.api.common.resources.Resource;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
...@@ -28,8 +29,6 @@ import java.util.HashMap; ...@@ -28,8 +29,6 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import static org.apache.flink.util.Preconditions.checkNotNull;
/** /**
* Describe the different resource factors of the operator with UDF. * Describe the different resource factors of the operator with UDF.
* *
...@@ -97,7 +96,7 @@ public class ResourceSpec implements Serializable { ...@@ -97,7 +96,7 @@ public class ResourceSpec implements Serializable {
this.stateSizeInMB = stateSizeInMB; this.stateSizeInMB = stateSizeInMB;
for (Resource resource : extendedResources) { for (Resource resource : extendedResources) {
if (resource != null) { if (resource != null) {
this.extendedResources.put(resource.name, resource); this.extendedResources.put(resource.getName(), resource);
} }
} }
} }
...@@ -118,7 +117,7 @@ public class ResourceSpec implements Serializable { ...@@ -118,7 +117,7 @@ public class ResourceSpec implements Serializable {
this.stateSizeInMB + other.stateSizeInMB); this.stateSizeInMB + other.stateSizeInMB);
target.extendedResources.putAll(extendedResources); target.extendedResources.putAll(extendedResources);
for (Resource resource : other.extendedResources.values()) { for (Resource resource : other.extendedResources.values()) {
target.extendedResources.merge(resource.name, resource, (v1, v2) -> v1.merge(v2)); target.extendedResources.merge(resource.getName(), resource, (v1, v2) -> v1.merge(v2));
} }
return target; return target;
} }
...@@ -148,9 +147,14 @@ public class ResourceSpec implements Serializable { ...@@ -148,9 +147,14 @@ public class ResourceSpec implements Serializable {
if (gpuResource != null) { if (gpuResource != null) {
return gpuResource.getValue(); return gpuResource.getValue();
} }
return 0.0; return 0.0;
} }
public Map<String, Resource> getExtendedResources() {
return extendedResources;
}
/** /**
* Check whether all the field values are valid. * Check whether all the field values are valid.
* *
...@@ -160,7 +164,7 @@ public class ResourceSpec implements Serializable { ...@@ -160,7 +164,7 @@ public class ResourceSpec implements Serializable {
if (this.cpuCores >= 0 && this.heapMemoryInMB >= 0 && this.directMemoryInMB >= 0 && if (this.cpuCores >= 0 && this.heapMemoryInMB >= 0 && this.directMemoryInMB >= 0 &&
this.nativeMemoryInMB >= 0 && this.stateSizeInMB >= 0) { this.nativeMemoryInMB >= 0 && this.stateSizeInMB >= 0) {
for (Resource resource : extendedResources.values()) { for (Resource resource : extendedResources.values()) {
if (resource.value < 0) { if (resource.getValue() < 0) {
return false; return false;
} }
} }
...@@ -185,9 +189,9 @@ public class ResourceSpec implements Serializable { ...@@ -185,9 +189,9 @@ public class ResourceSpec implements Serializable {
int cmp5 = Integer.compare(this.stateSizeInMB, other.stateSizeInMB); int cmp5 = Integer.compare(this.stateSizeInMB, other.stateSizeInMB);
if (cmp1 <= 0 && cmp2 <= 0 && cmp3 <= 0 && cmp4 <= 0 && cmp5 <= 0) { if (cmp1 <= 0 && cmp2 <= 0 && cmp3 <= 0 && cmp4 <= 0 && cmp5 <= 0) {
for (Resource resource : extendedResources.values()) { for (Resource resource : extendedResources.values()) {
if (!other.extendedResources.containsKey(resource.name) || if (!other.extendedResources.containsKey(resource.getName()) ||
!other.extendedResources.get(resource.name).type.equals(resource.type) || other.extendedResources.get(resource.getName()).getResourceAggregateType() != resource.getResourceAggregateType() ||
other.extendedResources.get(resource.name).value < resource.value) { other.extendedResources.get(resource.getName()).getValue() < resource.getValue()) {
return false; return false;
} }
} }
...@@ -229,7 +233,7 @@ public class ResourceSpec implements Serializable { ...@@ -229,7 +233,7 @@ public class ResourceSpec implements Serializable {
public String toString() { public String toString() {
String extend = ""; String extend = "";
for (Resource resource : extendedResources.values()) { for (Resource resource : extendedResources.values()) {
extend += ", " + resource.name + "=" + resource.value; extend += ", " + resource.getName() + "=" + resource.getValue();
} }
return "ResourceSpec{" + return "ResourceSpec{" +
"cpuCores=" + cpuCores + "cpuCores=" + cpuCores +
...@@ -297,121 +301,4 @@ public class ResourceSpec implements Serializable { ...@@ -297,121 +301,4 @@ public class ResourceSpec implements Serializable {
} }
} }
/**
* Base class for additional resources one can specify.
*/
public abstract static class Resource implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Enum defining how resources are aggregated.
*/
public enum ResourceAggregateType {
/**
* Denotes keeping the sum of the values with same name when merging two resource specs for operator chaining.
*/
AGGREGATE_TYPE_SUM,
/**
* Denotes keeping the max of the values with same name when merging two resource specs for operator chaining.
*/
AGGREGATE_TYPE_MAX
}
private final String name;
private final double value;
private final ResourceAggregateType type;
public Resource(String name, double value, ResourceAggregateType type) {
this.name = checkNotNull(name);
this.value = value;
this.type = checkNotNull(type);
}
Resource merge(Resource other) {
Preconditions.checkArgument(getClass() == other.getClass(), "Merge with different resource type");
Preconditions.checkArgument(this.name.equals(other.name), "Merge with different resource name");
Preconditions.checkArgument(this.type.equals(other.type), "Merge with different aggregate type");
Double value = null;
switch (type) {
case AGGREGATE_TYPE_MAX :
value = Math.max(other.value, this.value);
break;
case AGGREGATE_TYPE_SUM:
default:
value = this.value + other.value;
}
Resource resource = create(value, type);
return resource;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && getClass() == o.getClass()) {
Resource other = (Resource) o;
return name.equals(other.name) && type.equals(other.type) && value == other.value;
} else {
return false;
}
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + type.ordinal();
result = 31 * result + (int) value;
return result;
}
public String getName() {
return this.name;
}
public ResourceAggregateType getAggregateType() {
return this.type;
}
public double getValue() {
return this.value;
}
/**
* Create a resource of the same resource type.
*
* @param value The value of the resource
* @param type The aggregate type of the resource
* @return A new instance of the sub resource
*/
protected abstract Resource create(double value, ResourceAggregateType type);
}
/**
* The GPU resource.
*/
public static class GPUResource extends Resource {
private static final long serialVersionUID = -2276080061777135142L;
public GPUResource(double value) {
this(value, ResourceAggregateType.AGGREGATE_TYPE_SUM);
}
public GPUResource(double value, ResourceAggregateType type) {
super(GPU_NAME, value, type);
}
@Override
public Resource create(double value, ResourceAggregateType type) {
return new GPUResource(value, type);
}
}
} }
/*
* 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.flink.api.common.resources;
import org.apache.flink.annotation.Internal;
import org.apache.flink.api.common.operators.ResourceSpec;
/**
* The GPU resource.
*/
@Internal
public class GPUResource extends Resource {
private static final long serialVersionUID = -2276080061777135142L;
public GPUResource(double value) {
this(value, ResourceAggregateType.AGGREGATE_TYPE_SUM);
}
private GPUResource(double value, ResourceAggregateType type) {
super(ResourceSpec.GPU_NAME, value, type);
}
@Override
public Resource create(double value, ResourceAggregateType type) {
return new GPUResource(value, type);
}
}
/*
* 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.flink.api.common.resources;
import org.apache.flink.annotation.Internal;
import org.apache.flink.util.Preconditions;
import java.io.Serializable;
import static org.apache.flink.util.Preconditions.checkNotNull;
/**
* Base class for resources one can specify.
*/
@Internal
public abstract class Resource implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Enum defining how resources are aggregated.
*/
public enum ResourceAggregateType {
/**
* Denotes keeping the sum of the values with same name when merging two resource specs for operator chaining.
*/
AGGREGATE_TYPE_SUM,
/**
* Denotes keeping the max of the values with same name when merging two resource specs for operator chaining.
*/
AGGREGATE_TYPE_MAX
}
private final String name;
private final double value;
private final ResourceAggregateType resourceAggregateType;
protected Resource(String name, double value, ResourceAggregateType type) {
this.name = checkNotNull(name);
this.value = value;
this.resourceAggregateType = checkNotNull(type);
}
public Resource merge(Resource other) {
Preconditions.checkArgument(getClass() == other.getClass(), "Merge with different resource resourceAggregateType");
Preconditions.checkArgument(this.name.equals(other.name), "Merge with different resource name");
Preconditions.checkArgument(this.resourceAggregateType == other.resourceAggregateType, "Merge with different aggregate resourceAggregateType");
final double aggregatedValue;
switch (resourceAggregateType) {
case AGGREGATE_TYPE_MAX :
aggregatedValue = Math.max(other.value, this.value);
break;
case AGGREGATE_TYPE_SUM:
default:
aggregatedValue = this.value + other.value;
}
return create(aggregatedValue, resourceAggregateType);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && getClass() == o.getClass()) {
Resource other = (Resource) o;
return name.equals(other.name) && resourceAggregateType == other.resourceAggregateType && value == other.value;
} else {
return false;
}
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + resourceAggregateType.ordinal();
result = 31 * result + (int) value;
return result;
}
public String getName() {
return name;
}
public ResourceAggregateType getResourceAggregateType() {
return this.resourceAggregateType;
}
public double getValue() {
return this.value;
}
/**
* Create a resource of the same resource resourceAggregateType.
*
* @param value The value of the resource
* @param type The aggregate resourceAggregateType of the resource
* @return A new instance of the sub resource
*/
protected abstract Resource create(double value, ResourceAggregateType type);
}
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
package org.apache.flink.runtime.clusterframework.types; package org.apache.flink.runtime.clusterframework.types;
import org.apache.flink.api.common.resources.Resource;
import org.apache.flink.api.common.operators.ResourceSpec; import org.apache.flink.api.common.operators.ResourceSpec;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
...@@ -34,7 +35,7 @@ import java.util.Objects; ...@@ -34,7 +35,7 @@ import java.util.Objects;
* checked whether it can match another profile's requirement, and furthermore we may calculate a matching * checked whether it can match another profile's requirement, and furthermore we may calculate a matching
* score to decide which profile we should choose when we have lots of candidate slots. * score to decide which profile we should choose when we have lots of candidate slots.
* It should be generated from {@link ResourceSpec} with the input and output memory calculated in JobMaster. * It should be generated from {@link ResourceSpec} with the input and output memory calculated in JobMaster.
* *
* <p>Resource Profiles have a total ordering, defined by comparing these fields in sequence: * <p>Resource Profiles have a total ordering, defined by comparing these fields in sequence:
* <ol> * <ol>
* <li>Memory Size</li> * <li>Memory Size</li>
...@@ -51,20 +52,20 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile ...@@ -51,20 +52,20 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** How many cpu cores are needed, use double so we can specify cpu like 0.1 */ /** How many cpu cores are needed, use double so we can specify cpu like 0.1. */
private final double cpuCores; private final double cpuCores;
/** How many heap memory in mb are needed */ /** How many heap memory in mb are needed. */
private final int heapMemoryInMB; private final int heapMemoryInMB;
/** How many direct memory in mb are needed */ /** How many direct memory in mb are needed. */
private final int directMemoryInMB; private final int directMemoryInMB;
/** How many native memory in mb are needed */ /** How many native memory in mb are needed. */
private final int nativeMemoryInMB; private final int nativeMemoryInMB;
/** A extensible field for user specified resources from {@link ResourceSpec}. */ /** A extensible field for user specified resources from {@link ResourceSpec}. */
private final Map<String, ResourceSpec.Resource> extendedResources = new HashMap<>(1); private final Map<String, Resource> extendedResources = new HashMap<>(1);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
...@@ -82,7 +83,7 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile ...@@ -82,7 +83,7 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile
int heapMemoryInMB, int heapMemoryInMB,
int directMemoryInMB, int directMemoryInMB,
int nativeMemoryInMB, int nativeMemoryInMB,
Map<String, ResourceSpec.Resource> extendedResources) { Map<String, Resource> extendedResources) {
this.cpuCores = cpuCores; this.cpuCores = cpuCores;
this.heapMemoryInMB = heapMemoryInMB; this.heapMemoryInMB = heapMemoryInMB;
this.directMemoryInMB = directMemoryInMB; this.directMemoryInMB = directMemoryInMB;
...@@ -104,8 +105,8 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile ...@@ -104,8 +105,8 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile
/** /**
* Creates a copy of the given ResourceProfile. * Creates a copy of the given ResourceProfile.
* *
* @param other The ResourceProfile to copy. * @param other The ResourceProfile to copy.
*/ */
public ResourceProfile(ResourceProfile other) { public ResourceProfile(ResourceProfile other) {
this(other.cpuCores, other.heapMemoryInMB, other.directMemoryInMB, other.nativeMemoryInMB, other.extendedResources); this(other.cpuCores, other.heapMemoryInMB, other.directMemoryInMB, other.nativeMemoryInMB, other.extendedResources);
...@@ -172,7 +173,7 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile ...@@ -172,7 +173,7 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile
* *
* @return The extended resources * @return The extended resources
*/ */
public Map<String, ResourceSpec.Resource> getExtendedResources() { public Map<String, Resource> getExtendedResources() {
return Collections.unmodifiableMap(extendedResources); return Collections.unmodifiableMap(extendedResources);
} }
...@@ -187,9 +188,9 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile ...@@ -187,9 +188,9 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile
heapMemoryInMB >= required.getHeapMemoryInMB() && heapMemoryInMB >= required.getHeapMemoryInMB() &&
directMemoryInMB >= required.getDirectMemoryInMB() && directMemoryInMB >= required.getDirectMemoryInMB() &&
nativeMemoryInMB >= required.getNativeMemoryInMB()) { nativeMemoryInMB >= required.getNativeMemoryInMB()) {
for (Map.Entry<String, ResourceSpec.Resource> resource : required.extendedResources.entrySet()) { for (Map.Entry<String, Resource> resource : required.extendedResources.entrySet()) {
if (!extendedResources.containsKey(resource.getKey()) || if (!extendedResources.containsKey(resource.getKey()) ||
!extendedResources.get(resource.getKey()).getAggregateType().equals(resource.getValue().getAggregateType()) || !extendedResources.get(resource.getKey()).getResourceAggregateType().equals(resource.getValue().getResourceAggregateType()) ||
extendedResources.get(resource.getKey()).getValue() < resource.getValue().getValue()) { extendedResources.get(resource.getKey()).getValue() < resource.getValue().getValue()) {
return false; return false;
} }
...@@ -206,15 +207,15 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile ...@@ -206,15 +207,15 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile
cmp = Double.compare(this.cpuCores, other.cpuCores); cmp = Double.compare(this.cpuCores, other.cpuCores);
} }
if (cmp == 0) { if (cmp == 0) {
Iterator<Map.Entry<String, ResourceSpec.Resource>> thisIterator = extendedResources.entrySet().iterator(); Iterator<Map.Entry<String, Resource>> thisIterator = extendedResources.entrySet().iterator();
Iterator<Map.Entry<String, ResourceSpec.Resource>> otherIterator = other.extendedResources.entrySet().iterator(); Iterator<Map.Entry<String, Resource>> otherIterator = other.extendedResources.entrySet().iterator();
while (thisIterator.hasNext() && otherIterator.hasNext()) { while (thisIterator.hasNext() && otherIterator.hasNext()) {
Map.Entry<String, ResourceSpec.Resource> thisResource = thisIterator.next(); Map.Entry<String, Resource> thisResource = thisIterator.next();
Map.Entry<String, ResourceSpec.Resource> otherResource = otherIterator.next(); Map.Entry<String, Resource> otherResource = otherIterator.next();
if ((cmp = otherResource.getKey().compareTo(thisResource.getKey())) != 0) { if ((cmp = otherResource.getKey().compareTo(thisResource.getKey())) != 0) {
return cmp; return cmp;
} }
if (!otherResource.getValue().getAggregateType().equals(thisResource.getValue().getAggregateType())) { if (!otherResource.getValue().getResourceAggregateType().equals(thisResource.getValue().getResourceAggregateType())) {
return 1; return 1;
} }
if ((cmp = Double.compare(thisResource.getValue().getValue(), otherResource.getValue().getValue())) != 0) { if ((cmp = Double.compare(thisResource.getValue().getValue(), otherResource.getValue().getValue())) != 0) {
...@@ -261,32 +262,26 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile ...@@ -261,32 +262,26 @@ public class ResourceProfile implements Serializable, Comparable<ResourceProfile
@Override @Override
public String toString() { public String toString() {
String resourceStr = ""; final StringBuilder resources = new StringBuilder(extendedResources.size() * 10);
for (Map.Entry<String, ResourceSpec.Resource> resource : extendedResources.entrySet()) { for (Map.Entry<String, Resource> resource : extendedResources.entrySet()) {
resourceStr += ", " + resource.getKey() + "=" + resource.getValue(); resources.append(", ").append(resource.getKey()).append('=').append(resource.getValue());
} }
return "ResourceProfile{" + return "ResourceProfile{" +
"cpuCores=" + cpuCores + "cpuCores=" + cpuCores +
", heapMemoryInMB=" + heapMemoryInMB + ", heapMemoryInMB=" + heapMemoryInMB +
", directMemoryInMB=" + directMemoryInMB + ", directMemoryInMB=" + directMemoryInMB +
", nativeMemoryInMB=" + nativeMemoryInMB + resourceStr + ", nativeMemoryInMB=" + nativeMemoryInMB + resources +
'}'; '}';
} }
public static ResourceProfile fromResourceSpec( static ResourceProfile fromResourceSpec(ResourceSpec resourceSpec) {
ResourceSpec resourceSpec) { Map<String, Resource> copiedExtendedResources = new HashMap<>(resourceSpec.getExtendedResources());
Map<String, ResourceSpec.Resource> extendResource = new HashMap<>(1);
double gpu = resourceSpec.getGPUResource(); return new ResourceProfile(
if (gpu > 0) {
extendResource.put(ResourceSpec.GPU_NAME, new ResourceSpec.GPUResource(gpu));
}
ResourceProfile resourceProfile = new ResourceProfile(
resourceSpec.getCpuCores(), resourceSpec.getCpuCores(),
resourceSpec.getHeapMemory(), resourceSpec.getHeapMemory(),
resourceSpec.getDirectMemory(), resourceSpec.getDirectMemory(),
resourceSpec.getNativeMemory(), resourceSpec.getNativeMemory(),
extendResource copiedExtendedResources);
);
return resourceProfile;
} }
} }
...@@ -23,7 +23,7 @@ import org.apache.flink.api.common.accumulators.SerializedListAccumulator ...@@ -23,7 +23,7 @@ import org.apache.flink.api.common.accumulators.SerializedListAccumulator
import org.apache.flink.api.common.aggregators.Aggregator import org.apache.flink.api.common.aggregators.Aggregator
import org.apache.flink.api.common.functions._ import org.apache.flink.api.common.functions._
import org.apache.flink.api.common.io.{FileOutputFormat, OutputFormat} import org.apache.flink.api.common.io.{FileOutputFormat, OutputFormat}
import org.apache.flink.api.common.operators.{ResourceSpec, Keys, Order} import org.apache.flink.api.common.operators.{Keys, Order, ResourceSpec}
import org.apache.flink.api.common.operators.base.JoinOperatorBase.JoinHint import org.apache.flink.api.common.operators.base.JoinOperatorBase.JoinHint
import org.apache.flink.api.common.operators.base.CrossOperatorBase.CrossHint import org.apache.flink.api.common.operators.base.CrossOperatorBase.CrossHint
import org.apache.flink.api.common.operators.base.PartitionOperatorBase.PartitionMethod import org.apache.flink.api.common.operators.base.PartitionOperatorBase.PartitionMethod
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册