From 38739ddcfd42736f0cc5d4ba882a2656a89c91f7 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Wed, 11 Sep 2019 16:48:34 -0700 Subject: [PATCH 1/3] Add ResourcetopStateAntiAffinityConstraint The more total top state partitions assigned to the instance, the lower the score, vice versa. --- ...esourceTopStateAntiAffinityConstraint.java | 45 +++++++++++++ .../waged/model/AssignableNode.java | 6 +- ...esourceTopStateAntiAffinityConstraint.java | 65 +++++++++++++++++++ 3 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java create mode 100644 helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/constraints/TestResourceTopStateAntiAffinityConstraint.java diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java new file mode 100644 index 0000000000..c3fc5b0252 --- /dev/null +++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java @@ -0,0 +1,45 @@ +package org.apache.helix.controller.rebalancer.waged.constraints; + +/* + * 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. + */ + +import org.apache.helix.controller.rebalancer.waged.model.AssignableNode; +import org.apache.helix.controller.rebalancer.waged.model.AssignableReplica; +import org.apache.helix.controller.rebalancer.waged.model.ClusterContext; + +/** + * Evaluate the proposed assignment according to the top state replication count on the instacne. + * The more total top state partitions assigned to the instance, the lower the score, vice versa. + */ +public class ResourceTopStateAntiAffinityConstraint extends SoftConstraint { + @Override + protected float getAssignmentScore(AssignableNode node, AssignableReplica replica, + ClusterContext clusterContext) { + if (!replica.isReplicaTopState()) { + return (getMaxScore() + getMinScore()) / 2; + } + + int curTopPartitionCountForResource = node.getAssignedTopStatePartitionsCount(); + int doubleMaxTopStateCount = 2 * clusterContext.getEstimatedMaxTopStateCount(); + + return Math.max( + ((float) doubleMaxTopStateCount - curTopPartitionCountForResource) / doubleMaxTopStateCount, + 0); + } +} diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableNode.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableNode.java index f25c2894fb..6966353fa5 100644 --- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableNode.java +++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableNode.java @@ -187,10 +187,10 @@ public Set getAssignedTopStatePartitionsByResource(String resource) { /** * @return The total count of assigned top state partitions. */ - public long getAssignedTopStatePartitionsCount() { - return _currentAssignedReplicaMap.values().stream() + public int getAssignedTopStatePartitionsCount() { + return (int) _currentAssignedReplicaMap.values().stream() .flatMap(replicaMap -> replicaMap.values().stream()) - .filter(replica -> replica.isReplicaTopState()).count(); + .filter(AssignableReplica::isReplicaTopState).count(); } /** diff --git a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/constraints/TestResourceTopStateAntiAffinityConstraint.java b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/constraints/TestResourceTopStateAntiAffinityConstraint.java new file mode 100644 index 0000000000..06ef537a27 --- /dev/null +++ b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/constraints/TestResourceTopStateAntiAffinityConstraint.java @@ -0,0 +1,65 @@ +package org.apache.helix.controller.rebalancer.waged.constraints; + +/* + * 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. + */ + +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import org.apache.helix.controller.rebalancer.waged.model.AssignableNode; +import org.apache.helix.controller.rebalancer.waged.model.AssignableReplica; +import org.apache.helix.controller.rebalancer.waged.model.ClusterContext; +import org.mockito.Mockito; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class TestResourceTopStateAntiAffinityConstraint { + private final AssignableReplica _testReplica = Mockito.mock(AssignableReplica.class); + private final AssignableNode _testNode = Mockito.mock(AssignableNode.class); + private final ClusterContext _clusterContext = Mockito.mock(ClusterContext.class); + + private final SoftConstraint _constraint = new ResourceTopStateAntiAffinityConstraint(); + + @Test + public void testGetAssignmentScoreWhenReplicaNotTopState() { + when(_testReplica.isReplicaTopState()).thenReturn(false); + float score = _constraint.getAssignmentScore(_testNode, _testReplica, _clusterContext); + Assert.assertEquals(score, (_constraint.getMaxScore() + _constraint.getMinScore()) / 2); + verifyZeroInteractions(_testNode); + verifyZeroInteractions(_clusterContext); + } + + @Test + public void testGetAssignmentScoreWhenReplicaIsTopStateHeavyLoad() { + when(_testReplica.isReplicaTopState()).thenReturn(true); + when(_testNode.getAssignedTopStatePartitionsCount()).thenReturn(20); + when(_clusterContext.getEstimatedMaxTopStateCount()).thenReturn(20); + float score = _constraint.getAssignmentScore(_testNode, _testReplica, _clusterContext); + Assert.assertEquals(score, 0.5f); + } + + @Test + public void testGetAssignmentScoreWhenReplicaIsTopStateLightLoad() { + when(_testReplica.isReplicaTopState()).thenReturn(true); + when(_testNode.getAssignedTopStatePartitionsCount()).thenReturn(0); + when(_clusterContext.getEstimatedMaxTopStateCount()).thenReturn(20); + float score = _constraint.getAssignmentScore(_testNode, _testReplica, _clusterContext); + Assert.assertEquals(score, 1f); + } +} From a3c19c0adcc121118a114d0f747a7d77419fe697 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Wed, 11 Sep 2019 16:58:23 -0700 Subject: [PATCH 2/3] Update the doc --- .../constraints/ResourceTopStateAntiAffinityConstraint.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java index c3fc5b0252..345e15c5ba 100644 --- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java +++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java @@ -25,7 +25,8 @@ /** * Evaluate the proposed assignment according to the top state replication count on the instacne. - * The more total top state partitions assigned to the instance, the lower the score, vice versa. + * The higher number the number of top state partitions assigned to the instance, the lower the + * score, vice versa. */ public class ResourceTopStateAntiAffinityConstraint extends SoftConstraint { @Override From ef855bfc1013c6e61fd32c42b3766f5a98feb416 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Wed, 11 Sep 2019 17:13:31 -0700 Subject: [PATCH 3/3] Fix typo --- .../constraints/ResourceTopStateAntiAffinityConstraint.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java index 345e15c5ba..b1e64b9597 100644 --- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java +++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/constraints/ResourceTopStateAntiAffinityConstraint.java @@ -24,7 +24,7 @@ import org.apache.helix.controller.rebalancer.waged.model.ClusterContext; /** - * Evaluate the proposed assignment according to the top state replication count on the instacne. + * Evaluate the proposed assignment according to the top state replication count on the instance. * The higher number the number of top state partitions assigned to the instance, the lower the * score, vice versa. */