You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by lx...@apache.org on 2017/02/08 18:00:13 UTC

[38/38] helix git commit: Avoid moving partitions unnecessarily when auto-rebalancing using default AutoRebalanceStrategy.

Avoid moving partitions unnecessarily when auto-rebalancing using default AutoRebalanceStrategy.


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

Branch: refs/heads/helix-0.6.x
Commit: 3a61f5db14c9dfb6e09dfaf8aa4a52bb101af901
Parents: 45d76a2
Author: Lei Xia <lx...@linkedin.com>
Authored: Thu Nov 17 18:15:50 2016 -0800
Committer: Lei Xia <lx...@linkedin.com>
Committed: Wed Feb 8 09:58:09 2017 -0800

----------------------------------------------------------------------
 .../rebalancer/TestAutoRebalanceStrategy.java   | 59 ++++++++++++++++++++
 1 file changed, 59 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/helix/blob/3a61f5db/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java
index b73a992..2fb914c 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java
@@ -790,4 +790,63 @@ public class TestAutoRebalanceStrategy {
       Assert.assertEquals(p.size(), nReplicas);
     }
   }
+
+  /**
+   * Tests the following scenario: there is only a single partition for a resource. Two nodes up,
+   * partition should
+   * be assigned to one of them. Take down that node, partition should move. Bring back up that
+   * node, partition should not move unnecessarily.
+   */
+  @Test
+  public void testWontMoveSinglePartitionUnnecessarily() {
+    final String RESOURCE = "resource";
+    final String partition = "resource_0";
+    final StateModelDefinition STATE_MODEL =
+        new StateModelDefinition(StateModelConfigGenerator.generateConfigForOnlineOffline());
+    LinkedHashMap<String, Integer> stateCount = Maps.newLinkedHashMap();
+    stateCount.put("ONLINE", 1);
+    final String[] NODES = {"n0", "n1"};
+
+    // initial state, one node, no mapping
+    List<String> allNodes = Lists.newArrayList(NODES);
+    List<String> liveNodes = Lists.newArrayList(NODES);
+    Map<String, Map<String, String>> currentMapping = Maps.newHashMap();
+    currentMapping.put(partition, new HashMap<String, String>());
+
+    // Both nodes there
+    List<String> partitions = Lists.newArrayList(partition);
+    Map<String, String> upperBounds = Maps.newHashMap();
+    for (String state : STATE_MODEL.getStatesPriorityList()) {
+      upperBounds.put(state, STATE_MODEL.getNumInstancesPerState(state));
+    }
+
+    ZNRecord znRecord =
+        new AutoRebalanceStrategy(RESOURCE, partitions, stateCount, Integer.MAX_VALUE)
+            .computePartitionAssignment(allNodes, liveNodes, currentMapping, null);
+    Map<String, List<String>> preferenceLists = znRecord.getListFields();
+    List<String> preferenceList = preferenceLists.get(partition.toString());
+    Assert.assertNotNull(preferenceList, "invalid preference list for " + partition);
+    Assert.assertEquals(preferenceList.size(), 1, "invalid preference list for " + partition);
+    String state = znRecord.getMapField(partition.toString()).get(preferenceList.get(0));
+    Assert.assertEquals(state, "ONLINE", "Invalid state for " + partition);
+    String preferredNode = preferenceList.get(0);
+    String otherNode = preferredNode.equals(NODES[0]) ? NODES[1] : NODES[0];
+    // ok, see what happens if we've got the partition on the other node (e.g. due to the preferred
+    // node being down).
+    currentMapping.get(partition).put(otherNode, state);
+
+    znRecord =
+        new AutoRebalanceStrategy(RESOURCE, partitions, stateCount, Integer.MAX_VALUE)
+            .computePartitionAssignment(allNodes, liveNodes, currentMapping, null);
+
+    preferenceLists = znRecord.getListFields();
+    preferenceList = preferenceLists.get(partition.toString());
+    Assert.assertNotNull(preferenceList, "invalid preference list for " + partition);
+    Assert.assertEquals(preferenceList.size(), 1, "invalid preference list for " + partition);
+    state = znRecord.getMapField(partition.toString()).get(preferenceList.get(0));
+    Assert.assertEquals(state, "ONLINE", "Invalid state for " + partition);
+    String finalPreferredNode = preferenceList.get(0);
+    // finally, make sure we haven't moved it.
+    Assert.assertEquals(finalPreferredNode, otherNode);
+  }
 }