You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by kk...@apache.org on 2018/02/02 22:47:03 UTC
hadoop git commit: YARN-7778. Merging of placement constraints
defined at different levels. Contributed by Weiwei Yang.
Repository: hadoop
Updated Branches:
refs/heads/trunk b6e50fad5 -> 50723889c
YARN-7778. Merging of placement constraints defined at different levels. Contributed by Weiwei Yang.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/50723889
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/50723889
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/50723889
Branch: refs/heads/trunk
Commit: 50723889cc29e8dadfa6ab6afbb90ac798d66878
Parents: b6e50fa
Author: Konstantinos Karanasos <kk...@apache.org>
Authored: Fri Feb 2 14:43:54 2018 -0800
Committer: Konstantinos Karanasos <kk...@apache.org>
Committed: Fri Feb 2 14:46:20 2018 -0800
----------------------------------------------------------------------
.../MemoryPlacementConstraintManager.java | 42 ++++++++++
.../constraint/PlacementConstraintManager.java | 13 ++++
.../constraint/PlacementConstraintsUtil.java | 24 ++----
.../TestPlacementConstraintManagerService.java | 82 ++++++++++++++++++++
...stSingleConstraintAppPlacementAllocator.java | 5 ++
5 files changed, 150 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hadoop/blob/50723889/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/MemoryPlacementConstraintManager.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/MemoryPlacementConstraintManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/MemoryPlacementConstraintManager.java
index ceff6f6..5cb8b99 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/MemoryPlacementConstraintManager.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/MemoryPlacementConstraintManager.java
@@ -24,6 +24,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -33,6 +35,7 @@ import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.resource.PlacementConstraint;
+import org.apache.hadoop.yarn.api.resource.PlacementConstraints;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -237,6 +240,45 @@ public class MemoryPlacementConstraintManager
}
@Override
+ public PlacementConstraint getMultilevelConstraint(ApplicationId appId,
+ Set<String> sourceTags, PlacementConstraint schedulingRequestConstraint) {
+ List<PlacementConstraint> constraints = new ArrayList<>();
+ // Add scheduling request-level constraint.
+ if (schedulingRequestConstraint != null) {
+ constraints.add(schedulingRequestConstraint);
+ }
+ // Add app-level constraint if appId is given.
+ if (appId != null && sourceTags != null
+ && !sourceTags.isEmpty()) {
+ constraints.add(getConstraint(appId, sourceTags));
+ }
+ // Add global constraint.
+ if (sourceTags != null && !sourceTags.isEmpty()) {
+ constraints.add(getGlobalConstraint(sourceTags));
+ }
+
+ // Remove all null or duplicate constraints.
+ List<PlacementConstraint.AbstractConstraint> allConstraints =
+ constraints.stream()
+ .filter(placementConstraint -> placementConstraint != null
+ && placementConstraint.getConstraintExpr() != null)
+ .map(PlacementConstraint::getConstraintExpr)
+ .distinct()
+ .collect(Collectors.toList());
+
+ // Compose an AND constraint
+ // When merge request(RC), app(AC) and global constraint(GC),
+ // we do a merge on them with CC=AND(GC, AC, RC) and returns a
+ // composite AND constraint. Subsequently we check if CC could
+ // be satisfied. This ensures that every level of constraint
+ // is satisfied.
+ PlacementConstraint.And andConstraint = PlacementConstraints.and(
+ allConstraints.toArray(new PlacementConstraint
+ .AbstractConstraint[allConstraints.size()]));
+ return andConstraint.build();
+ }
+
+ @Override
public void unregisterApplication(ApplicationId appId) {
try {
writeLock.lock();
http://git-wip-us.apache.org/repos/asf/hadoop/blob/50723889/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintManager.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintManager.java
index 7725d0d..bf2365c 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintManager.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintManager.java
@@ -105,6 +105,19 @@ public interface PlacementConstraintManager {
PlacementConstraint getGlobalConstraint(Set<String> sourceTags);
/**
+ * Consider all levels of constraints (scheduling request, app, cluster) and
+ * return a merged constraint.
+ *
+ * @param applicationId application ID
+ * @param sourceTags a set of source allocation tags
+ * @param schedulingRequestConstraint placement constraint at scheduling
+ * request level
+ * @return a merged placement constraint
+ */
+ PlacementConstraint getMultilevelConstraint(ApplicationId applicationId,
+ Set<String> sourceTags, PlacementConstraint schedulingRequestConstraint);
+
+ /**
* Remove the constraints that correspond to a given application.
*
* @param appId the application that will be removed.
http://git-wip-us.apache.org/repos/asf/hadoop/blob/50723889/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintsUtil.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintsUtil.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintsUtil.java
index 6396e57..ab0bbd7 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintsUtil.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/PlacementConstraintsUtil.java
@@ -248,22 +248,14 @@ public final class PlacementConstraintsUtil {
SchedulingRequest request, SchedulerNode schedulerNode,
PlacementConstraintManager pcm, AllocationTagsManager atm)
throws InvalidAllocationTagsQueryException {
- // TODO do proper merge on different level of constraints, see YARN-7778.
-
- // Request level constraint
- PlacementConstraint constraint = request.getPlacementConstraint();
- if (constraint == null) {
- // Application level constraint
- constraint = pcm.getConstraint(applicationId,
- request.getAllocationTags());
- if (constraint == null) {
- // Global level constraint
- constraint = pcm.getGlobalConstraint(request.getAllocationTags());
- if (constraint == null) {
- return true;
- }
- }
+ Set<String> sourceTags = null;
+ PlacementConstraint pc = null;
+ if (request != null) {
+ sourceTags = request.getAllocationTags();
+ pc = request.getPlacementConstraint();
}
- return canSatisfyConstraints(applicationId, constraint, schedulerNode, atm);
+ return canSatisfyConstraints(applicationId,
+ pcm.getMultilevelConstraint(applicationId, sourceTags, pc),
+ schedulerNode, atm);
}
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/50723889/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/TestPlacementConstraintManagerService.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/TestPlacementConstraintManagerService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/TestPlacementConstraintManagerService.java
index abcab1a..976906d 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/TestPlacementConstraintManagerService.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/constraint/TestPlacementConstraintManagerService.java
@@ -34,8 +34,11 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import com.google.common.collect.Sets;
import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.SchedulingRequest;
import org.apache.hadoop.yarn.api.resource.PlacementConstraint;
+import org.apache.hadoop.yarn.api.resource.PlacementConstraint.And;
import org.apache.hadoop.yarn.api.resource.PlacementConstraints;
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
import org.junit.Assert;
@@ -179,4 +182,83 @@ public class TestPlacementConstraintManagerService {
Assert.assertTrue(pcm.validateConstraint(sourceTag1, c1));
Assert.assertFalse(pcm.validateConstraint(sourceTag4, c1));
}
+
+ @Test
+ public void testGetRequestConstraint() {
+ // Request Constraint(RC), App Constraint(AC), Global Constraint(GC)
+ PlacementConstraint constraint;
+ And mergedConstraint;
+ SchedulingRequest request;
+
+ // RC = c1
+ // AC = null
+ // GC = null
+ constraint = pcm.getMultilevelConstraint(appId1, null, c1);
+ Assert.assertTrue(constraint.getConstraintExpr() instanceof And);
+ mergedConstraint = (And) constraint.getConstraintExpr();
+ Assert.assertEquals(1, mergedConstraint.getChildren().size());
+ Assert.assertEquals(c1, mergedConstraint.getChildren().get(0).build());
+
+ // RC = null
+ // AC = tag1->c1, tag2->c2
+ // GC = null
+ pcm.registerApplication(appId1, constraintMap1);
+ // if the source tag in the request is not mapped to any existing
+ // registered constraint, we should get an empty AND constraint.
+ constraint = pcm.getMultilevelConstraint(appId1,
+ Sets.newHashSet("not_exist_tag"), null);
+ Assert.assertTrue(constraint.getConstraintExpr() instanceof And);
+ mergedConstraint = (And) constraint.getConstraintExpr();
+ // AND()
+ Assert.assertEquals(0, mergedConstraint.getChildren().size());
+ // if a mapping is found for a given source tag
+ constraint = pcm.getMultilevelConstraint(appId1, sourceTag1, null);
+ Assert.assertTrue(constraint.getConstraintExpr() instanceof And);
+ mergedConstraint = (And) constraint.getConstraintExpr();
+ // AND(c1)
+ Assert.assertEquals(1, mergedConstraint.getChildren().size());
+ Assert.assertEquals(c1, mergedConstraint.getChildren().get(0).build());
+ pcm.unregisterApplication(appId1);
+
+ // RC = null
+ // AC = null
+ // GC = tag1->c1
+ pcm.addGlobalConstraint(sourceTag1, c1, true);
+ constraint = pcm.getMultilevelConstraint(appId1,
+ Sets.newHashSet(sourceTag1), null);
+ Assert.assertTrue(constraint.getConstraintExpr() instanceof And);
+ mergedConstraint = (And) constraint.getConstraintExpr();
+ // AND(c1)
+ Assert.assertEquals(1, mergedConstraint.getChildren().size());
+ Assert.assertEquals(c1, mergedConstraint.getChildren().get(0).build());
+ pcm.removeGlobalConstraint(sourceTag1);
+
+ // RC = c2
+ // AC = tag1->c1, tag2->c2
+ // GC = tag1->c3
+ pcm.addGlobalConstraint(sourceTag1, c3, true);
+ pcm.registerApplication(appId1, constraintMap1);
+ // both RC, AC and GC should be respected
+ constraint = pcm.getMultilevelConstraint(appId1, sourceTag1, c2);
+ Assert.assertTrue(constraint.getConstraintExpr() instanceof And);
+ mergedConstraint = (And) constraint.getConstraintExpr();
+ // AND(c1, c2, c3)
+ Assert.assertEquals(3, mergedConstraint.getChildren().size());
+ pcm.removeGlobalConstraint(sourceTag1);
+ pcm.unregisterApplication(appId1);
+
+ // RC = c1
+ // AC = tag1->c1, tag2->c2
+ // GC = tag1->c2
+ pcm.addGlobalConstraint(sourceTag1, c2, true);
+ pcm.registerApplication(appId1, constraintMap1);
+ constraint = pcm.getMultilevelConstraint(appId1,
+ Sets.newHashSet(sourceTag1), c1);
+ Assert.assertTrue(constraint.getConstraintExpr() instanceof And);
+ mergedConstraint = (And) constraint.getConstraintExpr();
+ // AND(c1, c2)
+ Assert.assertEquals(2, mergedConstraint.getChildren().size());
+ pcm.removeGlobalConstraint(sourceTag1);
+ pcm.unregisterApplication(appId1);
+ }
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/50723889/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/placement/TestSingleConstraintAppPlacementAllocator.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/placement/TestSingleConstraintAppPlacementAllocator.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/placement/TestSingleConstraintAppPlacementAllocator.java
index 3485ea8..9be56ff 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/placement/TestSingleConstraintAppPlacementAllocator.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/placement/TestSingleConstraintAppPlacementAllocator.java
@@ -36,6 +36,8 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.Scheduli
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.TestUtils;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.constraint.AllocationTagsManager;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.constraint.InvalidAllocationTagsQueryException;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.constraint.MemoryPlacementConstraintManager;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.constraint.PlacementConstraintManager;
import org.apache.hadoop.yarn.server.scheduler.SchedulerRequestKey;
import org.junit.Assert;
import org.junit.Before;
@@ -76,10 +78,13 @@ public class TestSingleConstraintAppPlacementAllocator {
// Create allocation tags manager
AllocationTagsManager allocationTagsManager = new AllocationTagsManager(
rmContext);
+ PlacementConstraintManager placementConstraintManager =
+ new MemoryPlacementConstraintManager();
spyAllocationTagsManager = spy(allocationTagsManager);
schedulerRequestKey = new SchedulerRequestKey(Priority.newInstance(1), 2L,
TestUtils.getMockContainerId(1, 1));
rmContext.setAllocationTagsManager(spyAllocationTagsManager);
+ rmContext.setPlacementConstraintManager(placementConstraintManager);
// Create allocator
allocator = new SingleConstraintAppPlacementAllocator();
---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org