helix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zzh...@apache.org
Subject git commit: HELIX-150: Auto rebalance might not evenly distribute states across nodes
Date Mon, 29 Jul 2013 23:21:13 GMT
Updated Branches:
  refs/heads/master 937bc9aa0 -> 1a8216848


HELIX-150: Auto rebalance might not evenly distribute states across nodes


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

Branch: refs/heads/master
Commit: 1a82168488b06f75506932f0171e9ca17423468c
Parents: 937bc9a
Author: zzhang <zzhang5@uci.edu>
Authored: Mon Jul 29 16:21:05 2013 -0700
Committer: zzhang <zzhang5@uci.edu>
Committed: Mon Jul 29 16:21:05 2013 -0700

----------------------------------------------------------------------
 .../strategy/AutoRebalanceStrategy.java         | 48 ++++++++++++++++----
 1 file changed, 39 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/1a821684/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 58f5f17..9a998eb 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
@@ -110,6 +110,7 @@ public class AutoRebalanceStrategy implements Rebalancer {
 
     private Map<String, Node> _nodeMap;
     private List<Node> _liveNodesList;
+    private Map<String, Map<Integer, Integer>> _replicaIdMap;
     private Map<Replica, Node> _preferredAssignment;
     private Map<Replica, Node> _existingNonPreferredAssignment;
     private Set<Replica> _orphaned;
@@ -155,6 +156,10 @@ public class AutoRebalanceStrategy implements Rebalancer {
         node.capacity = targetSize;
         _liveNodesList.add(node);
       }
+
+      // compute global ids for all replicas
+      _replicaIdMap = generateReplicaMap();
+
       // compute the preferred mapping if all nodes were up
       _preferredAssignment = computePreferredPlacement(allNodes);
       // logger.info("preferred mapping:"+ preferredAssignment);
@@ -297,14 +302,15 @@ public class AutoRebalanceStrategy implements Rebalancer {
       for (String state : _states.keySet()) {
         int count = _states.get(state);
         for (int replicaId = 0; replicaId < count; replicaId++) {
+          int globalReplicaId = _replicaIdMap.get(state).get(replicaId);
           for (Node node : _liveNodesList) {
             for (Replica replica : node.preferred) {
-              if (replica.state.equals(state) && replicaId == replica.replicaId)
{
+              if (replica.state.equals(state) && globalReplicaId == replica.replicaId)
{
                 znRecord.getListField(replica.partition).add(node.id);
               }
             }
             for (Replica replica : node.nonPreferred) {
-              if (replica.state.equals(state) && replicaId == replica.replicaId)
{
+              if (replica.state.equals(state) && globalReplicaId == replica.replicaId)
{
                 znRecord.getListField(replica.partition).add(node.id);
               }
             }
@@ -340,7 +346,8 @@ public class AutoRebalanceStrategy implements Rebalancer {
           }
           // check if its in one of the preferred position
           for (int i = 0; i < count; i++) {
-            Replica replica = new Replica(partition, state, i);
+            int replicaId = _replicaIdMap.get(state).get(i);
+            Replica replica = new Replica(partition, state, replicaId);
             if (_preferredAssignment.get(replica).id != node.id) {
               existingNonPreferredAssignment.put(replica, node);
               node.nonPreferred.add(replica);
@@ -366,7 +373,8 @@ public class AutoRebalanceStrategy implements Rebalancer {
           Integer count = _states.get(state);
           // remove from orphaned if possible
           for (int i = 0; i < count; i++) {
-            Replica replica = new Replica(partition, state, i);
+            int replicaId = _replicaIdMap.get(state).get(i);
+            Replica replica = new Replica(partition, state, replicaId);
             if (orphanedPartitions.contains(replica)) {
               orphanedPartitions.remove(replica);
               break;
@@ -395,7 +403,8 @@ public class AutoRebalanceStrategy implements Rebalancer {
           Integer count = _states.get(state);
           // check if its in one of the preferred position
           for (int i = 0; i < count; i++) {
-            Replica replica = new Replica(partition, state, i);
+            int replicaId = _replicaIdMap.get(state).get(i);
+            Replica replica = new Replica(partition, state, replicaId);
             if (_preferredAssignment.containsKey(replica)
                 && !existingPreferredAssignment.containsKey(replica)
                 && _preferredAssignment.get(replica).id == node.id) {
@@ -424,7 +433,7 @@ public class AutoRebalanceStrategy implements Rebalancer {
         int replicaId = 0;
         for (String state : _states.keySet()) {
           for (int i = 0; i < _states.get(state); i++) {
-            Replica replica = new Replica(partition, state, i);
+            Replica replica = new Replica(partition, state, replicaId);
             int index;
             if (allNodes.size() > _partitions.size()) {
               // assign replicas in partition order in case there are more nodes than partitions
@@ -461,6 +470,27 @@ public class AutoRebalanceStrategy implements Rebalancer {
     }
 
     /**
+     * Compute a map of local replica ids to global replica ids. Local replica ids are relative
to
+     * a state of a partition, while global ids are relative to the partition as a whole
+     * @return A map of (state, local id) to global id
+     */
+    private Map<String, Map<Integer, Integer>> generateReplicaMap() {
+      int replicaId = 0;
+      Map<String, Map<Integer, Integer>> stateToIdMap =
+          new HashMap<String, Map<Integer, Integer>>();
+      for (String state : _states.keySet()) {
+        Integer count = _states.get(state);
+        Map<Integer, Integer> localToGlobalMap = new HashMap<Integer, Integer>();
+        for (int i = 0; i < count; i++) {
+          localToGlobalMap.put(i, replicaId);
+          replicaId++;
+        }
+        stateToIdMap.put(state, localToGlobalMap);
+      }
+      return stateToIdMap;
+    }
+
+    /**
      * A Node is an entity that can serve replicas. It has a capacity and knowledge
      * of replicas assigned to it, so it can decide if it can receive additional replicas.
      */
@@ -523,19 +553,19 @@ public class AutoRebalanceStrategy implements Rebalancer {
 
       private String partition;
       private String state;
-      private int replicaId;
+      private int replicaId; // this is a partition-relative id
       private String format;
 
       public Replica(String partition, String state, int replicaId) {
         this.partition = partition;
         this.state = state;
         this.replicaId = replicaId;
-        this.format = partition + "|" + state + "|" + replicaId;
+        this.format = partition + "|" + replicaId;
       }
 
       @Override
       public String toString() {
-        return format;
+        return format + "|" + state;
       }
 
       @Override


Mime
View raw message