You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by zz...@apache.org on 2014/11/14 02:26:22 UTC

helix git commit: [HELIX-547] AutoRebalancer may not converge in some rare situation, rb=28023

Repository: helix
Updated Branches:
  refs/heads/helix-0.6.x 8d464cf8f -> 961a9e1fe


[HELIX-547] AutoRebalancer may not converge in some rare situation, rb=28023


Project: http://git-wip-us.apache.org/repos/asf/helix/repo
Commit: http://git-wip-us.apache.org/repos/asf/helix/commit/961a9e1f
Tree: http://git-wip-us.apache.org/repos/asf/helix/tree/961a9e1f
Diff: http://git-wip-us.apache.org/repos/asf/helix/diff/961a9e1f

Branch: refs/heads/helix-0.6.x
Commit: 961a9e1feb09b707160c7d2d5234549cf4677956
Parents: 8d464cf
Author: zzhang <zz...@apache.org>
Authored: Thu Nov 13 17:26:06 2014 -0800
Committer: zzhang <zz...@apache.org>
Committed: Thu Nov 13 17:26:06 2014 -0800

----------------------------------------------------------------------
 .../strategy/AutoRebalanceStrategy.java         | 26 +++++++++++++++-----
 1 file changed, 20 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/helix/blob/961a9e1f/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
index 768286b..1e7f275 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
@@ -328,6 +328,7 @@ public class AutoRebalanceStrategy {
    */
   private void normalizePreferenceLists(Map<String, List<String>> preferenceLists,
       Map<String, List<String>> newPreferences) {
+
     Map<String, Map<String, Integer>> nodeReplicaCounts =
         new HashMap<String, Map<String, Integer>>();
     for (String partition : preferenceLists.keySet()) {
@@ -346,10 +347,12 @@ public class AutoRebalanceStrategy {
    */
   private void normalizePreferenceList(List<String> preferenceList,
       Map<String, Map<String, Integer>> nodeReplicaCounts) {
-    // make this a LinkedHashSet to preserve iteration order
-    Set<String> notAssigned = new LinkedHashSet<String>(preferenceList);
     List<String> newPreferenceList = new ArrayList<String>();
     int replicas = Math.min(countStateReplicas(), preferenceList.size());
+
+    // make this a LinkedHashSet to preserve iteration order
+    // truncate preference list to match replicas, @see HELIX-547
+    Set<String> notAssigned = new LinkedHashSet<String>(preferenceList.subList(0, replicas));
     for (int i = 0; i < replicas; i++) {
       String state = _stateMap.get(i);
       String node = getMinimumNodeForReplica(state, notAssigned, nodeReplicaCounts);
@@ -435,10 +438,21 @@ public class AutoRebalanceStrategy {
         for (int replicaId = 0; replicaId < count; replicaId++) {
           Replica replica = new Replica(partition, replicaId);
           if (_preferredAssignment.get(replica).id != node.id
-              && !_existingPreferredAssignment.containsKey(replica)
-              && !existingNonPreferredAssignment.containsKey(replica)) {
-            existingNonPreferredAssignment.put(replica, node);
-            node.nonPreferred.add(replica);
+              && !_existingPreferredAssignment.containsKey(replica)) {
+            if (!existingNonPreferredAssignment.containsKey(replica)) {
+              existingNonPreferredAssignment.put(replica, node);
+              node.nonPreferred.add(replica);
+            } else {
+              // if we have more than 1 existing non-preferred assignment, choose the node with more head-room
+              // this intends to make algorithm deterministic, @see HELIX-547
+              Node curNode = existingNonPreferredAssignment.get(replica);
+              int curHeadroom = curNode.capacity - curNode.currentlyAssigned;
+              int newHeadroon = node.capacity - node.currentlyAssigned;
+              if (newHeadroon > curHeadroom) {
+                existingNonPreferredAssignment.put(replica, node);
+                node.nonPreferred.add(replica);
+              }
+            }
             break;
           }
         }