Improve BestPossibleExternalViewVerifier by avoid fully refreshing entire 
cluster data everytime and avoid to calulate bestpossible states for not 
required resources.


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

Branch: refs/heads/master
Commit: fe970550b14ced339ffa657c98301a8b91f7abfb
Parents: 8c5fe2c
Author: Lei Xia <l...@linkedin.com>
Authored: Mon Jun 11 09:31:00 2018 -0700
Committer: Junkai Xue <j...@linkedin.com>
Committed: Thu Jul 12 17:02:13 2018 -0700

----------------------------------------------------------------------
 .../BestPossibleExternalViewVerifier.java       | 57 ++++++++++++++------
 1 file changed, 42 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/helix/blob/fe970550/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
----------------------------------------------------------------------
diff --git 
a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
 
b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
index b3fcdf0..4abfd07 100644
--- 
a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
+++ 
b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
@@ -36,6 +36,7 @@ import org.apache.helix.manager.zk.ZkClient;
 import org.apache.helix.model.ExternalView;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.Partition;
+import org.apache.helix.model.Resource;
 import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.task.TaskConstants;
 import org.slf4j.Logger;
@@ -61,6 +62,7 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
   private final Map<String, Map<String, String>> _errStates;
   private final Set<String> _resources;
   private final Set<String> _expectLiveInstances;
+  private final ClusterDataCache _clusterDataCache;
 
   public BestPossibleExternalViewVerifier(String zkAddr, String clusterName, 
Set<String> resources,
       Map<String, Map<String, String>> errStates, Set<String> 
expectLiveInstances) {
@@ -68,6 +70,7 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
     _errStates = errStates;
     _resources = resources;
     _expectLiveInstances = expectLiveInstances;
+    _clusterDataCache = new ClusterDataCache();
   }
 
   public BestPossibleExternalViewVerifier(ZkClient zkClient, String 
clusterName,
@@ -77,6 +80,18 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
     _errStates = errStates;
     _resources = resources;
     _expectLiveInstances = expectLiveInstances;
+    _clusterDataCache = new ClusterDataCache();
+  }
+
+  public static void main (String [] args) {
+    Set<String> resources = Collections.singleton("SyncColoTestDB");
+    BestPossibleExternalViewVerifier verifier =
+        new BestPossibleExternalViewVerifier.Builder("ESPRESSO_MT1")
+            .setZkAddr("zk-ltx1-espresso.stg.linkedin.com:12913")
+            .setResources(resources)
+            .build();
+
+    verifier.verify();
   }
 
   public static class Builder {
@@ -184,11 +199,11 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
   protected synchronized boolean verifyState() {
     try {
       PropertyKey.Builder keyBuilder = _accessor.keyBuilder();
-      // read cluster once and do verification
-      ClusterDataCache cache = new ClusterDataCache();
-      cache.refresh(_accessor);
 
-      Map<String, IdealState> idealStates = new 
HashMap<>(cache.getIdealStates());
+      _clusterDataCache.requireFullRefresh();
+      _clusterDataCache.refresh(_accessor);
+
+      Map<String, IdealState> idealStates = new 
HashMap<>(_clusterDataCache.getIdealStates());
 
       // filter out all resources that use Task state model
       Iterator<Map.Entry<String, IdealState>> it = 
idealStates.entrySet().iterator();
@@ -201,7 +216,7 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
 
       // verify live instances.
       if (_expectLiveInstances != null && !_expectLiveInstances.isEmpty()) {
-        Set<String> actualLiveNodes = cache.getLiveInstances().keySet();
+        Set<String> actualLiveNodes = 
_clusterDataCache.getLiveInstances().keySet();
         if (!_expectLiveInstances.equals(actualLiveNodes)) {
           LOG.warn("Live instances are not as expected. Actual live nodes: " + 
actualLiveNodes.toString());
           return false;
@@ -231,7 +246,7 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
       }
 
       // calculate best possible state
-      BestPossibleStateOutput bestPossOutput = calcBestPossState(cache);
+      BestPossibleStateOutput bestPossOutput = 
calcBestPossState(_clusterDataCache, _resources);
       Map<String, Map<Partition, Map<String, String>>> bestPossStateMap =
           bestPossOutput.getStateMap();
 
@@ -271,7 +286,7 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
         PartitionStateMap bpStateMap =
             bestPossOutput.getPartitionStateMap(resourceName);
 
-        StateModelDefinition stateModelDef = 
cache.getStateModelDef(is.getStateModelDefRef());
+        StateModelDefinition stateModelDef = 
_clusterDataCache.getStateModelDef(is.getStateModelDefRef());
         if (stateModelDef == null) {
           LOG.error(
               "State model definition " + is.getStateModelDefRef() + " for 
resource not found!" + is
@@ -300,16 +315,16 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
 
   private boolean verifyExternalView(ExternalView externalView,
       PartitionStateMap bestPossibleState, StateModelDefinition stateModelDef) 
{
-    Set<String> ignoreStaes = new HashSet<>(
+    Set<String> ignoreStates = new HashSet<>(
         Arrays.asList(stateModelDef.getInitialState(), 
HelixDefinedState.DROPPED.toString()));
 
     Map<String, Map<String, String>> bestPossibleStateMap =
         convertBestPossibleState(bestPossibleState);
 
-    removeEntryWithIgnoredStates(bestPossibleStateMap.entrySet().iterator(), 
ignoreStaes);
+    removeEntryWithIgnoredStates(bestPossibleStateMap.entrySet().iterator(), 
ignoreStates);
 
     Map<String, Map<String, String>> externalViewMap = 
externalView.getRecord().getMapFields();
-    removeEntryWithIgnoredStates(externalViewMap.entrySet().iterator(), 
ignoreStaes);
+    removeEntryWithIgnoredStates(externalViewMap.entrySet().iterator(), 
ignoreStates);
 
     return externalViewMap.equals(bestPossibleStateMap);
   }
@@ -349,22 +364,34 @@ public class BestPossibleExternalViewVerifier extends 
ZkHelixClusterVerifier {
    * kick off the BestPossibleStateCalcStage we are providing an empty current 
state map
    *
    * @param cache
+   * @param resources
    * @return
    * @throws Exception
    */
-  private BestPossibleStateOutput calcBestPossState(ClusterDataCache cache) 
throws Exception {
+  private BestPossibleStateOutput calcBestPossState(ClusterDataCache cache, 
Set<String> resources)
+      throws Exception {
     ClusterEvent event = new ClusterEvent(ClusterEventType.StateVerifier);
     event.addAttribute(AttributeName.ClusterDataCache.name(), cache);
 
     runStage(event, new ResourceComputationStage());
-    runStage(event, new CurrentStateComputationStage());
 
+    if (resources != null && !resources.isEmpty()) {
+      // Filtering out all non-required resources
+      final Map<String, Resource> resourceMap = 
event.getAttribute(AttributeName.RESOURCES.name());
+      resourceMap.keySet().retainAll(resources);
+      event.addAttribute(AttributeName.RESOURCES.name(), resourceMap);
+
+      final Map<String, Resource> resourceMapToRebalance =
+          event.getAttribute(AttributeName.RESOURCES_TO_REBALANCE.name());
+      resourceMapToRebalance.keySet().retainAll(resources);
+      event.addAttribute(AttributeName.RESOURCES_TO_REBALANCE.name(), 
resourceMapToRebalance);
+    }
+
+    runStage(event, new CurrentStateComputationStage());
     // TODO: be caution here, should be handled statelessly.
     runStage(event, new BestPossibleStateCalcStage());
 
-    BestPossibleStateOutput output =
-        event.getAttribute(AttributeName.BEST_POSSIBLE_STATE.name());
-
+    BestPossibleStateOutput output = 
event.getAttribute(AttributeName.BEST_POSSIBLE_STATE.name());
     return output;
   }
 

Reply via email to