This is an automated email from the ASF dual-hosted git repository.

zhangduo pushed a commit to branch branch-2.4
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2.4 by this push:
     new 69e93c8  HBASE-25767 CandidateGenerator.getRandomIterationOrder is too 
slow on large cluster (#3149)
69e93c8 is described below

commit 69e93c8137b90c507eef6bbb833a73157bc11b90
Author: Duo Zhang <[email protected]>
AuthorDate: Tue Apr 13 23:00:54 2021 +0800

    HBASE-25767 CandidateGenerator.getRandomIterationOrder is too slow on large 
cluster (#3149)
    
    Signed-off-by: XinSun <[email protected]>
    Signed-off-by: Yulin Niu <[email protected]>
---
 .../hbase/master/balancer/CandidateGenerator.java  | 18 ------
 .../balancer/LocalityBasedCandidateGenerator.java  | 72 +++++++++-------------
 .../master/balancer/StochasticLoadBalancer.java    | 17 +++--
 3 files changed, 37 insertions(+), 70 deletions(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
index e74e865..ee610a9 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
@@ -18,13 +18,8 @@
 
 package org.apache.hadoop.hbase.master.balancer;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 import java.util.Map;
-
 import org.apache.hadoop.hbase.client.RegionInfo;
-
 import org.apache.yetus.audience.InterfaceAudience;
 
 /**
@@ -135,17 +130,4 @@ abstract class CandidateGenerator {
       return BaseLoadBalancer.Cluster.NullAction;
     }
   }
-
-  /**
-   * Returns a random iteration order of indexes of an array with size length
-   */
-  List<Integer> getRandomIterationOrder(int length) {
-    ArrayList<Integer> order = new ArrayList<>(length);
-    for (int i = 0; i < length; i++) {
-      order.add(i);
-    }
-    Collections.shuffle(order);
-    return order;
-  }
-
 }
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
index 6afb86f..70b4f73 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
@@ -18,42 +18,30 @@
 
 package org.apache.hadoop.hbase.master.balancer;
 
-import org.apache.hadoop.hbase.master.MasterServices;
-
-import org.apache.hbase.thirdparty.com.google.common.base.Optional;
-
+import java.util.Optional;
+import java.util.concurrent.ThreadLocalRandom;
 import org.apache.yetus.audience.InterfaceAudience;
 
 @InterfaceAudience.Private
 class LocalityBasedCandidateGenerator extends CandidateGenerator {
 
-  private MasterServices masterServices;
-
-  LocalityBasedCandidateGenerator(MasterServices masterServices) {
-    this.masterServices = masterServices;
-  }
-
   @Override
   BaseLoadBalancer.Cluster.Action generate(BaseLoadBalancer.Cluster cluster) {
-    if (this.masterServices == null) {
-      int thisServer = pickRandomServer(cluster);
-      // Pick the other server
-      int otherServer = pickOtherRandomServer(cluster, thisServer);
-      return pickRandomRegions(cluster, thisServer, otherServer);
-    }
-
-    // Randomly iterate through regions until you find one that is not on 
ideal host
-    for (int region : getRandomIterationOrder(cluster.numRegions)) {
-      int currentServer = cluster.regionIndexToServerIndex[region];
-      if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(
-        BaseLoadBalancer.Cluster.LocalityType.SERVER)[region]) {
-        Optional<BaseLoadBalancer.Cluster.Action> potential = 
tryMoveOrSwap(cluster,
-          currentServer, region,
-          cluster.getOrComputeRegionsToMostLocalEntities(
-            BaseLoadBalancer.Cluster.LocalityType.SERVER)[region]
-        );
-        if (potential.isPresent()) {
-          return potential.get();
+    // iterate through regions until you find one that is not on ideal host
+    // start from a random point to avoid always balance the regions in front
+    if (cluster.numRegions > 0) {
+      int startIndex = ThreadLocalRandom.current().nextInt(cluster.numRegions);
+      for (int i = 0; i < cluster.numRegions; i++) {
+        int region = (startIndex + i) % cluster.numRegions;
+        int currentServer = cluster.regionIndexToServerIndex[region];
+        if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(
+          BaseLoadBalancer.Cluster.LocalityType.SERVER)[region]) {
+          Optional<BaseLoadBalancer.Cluster.Action> potential = 
tryMoveOrSwap(cluster,
+            currentServer, region, 
cluster.getOrComputeRegionsToMostLocalEntities(
+              BaseLoadBalancer.Cluster.LocalityType.SERVER)[region]);
+          if (potential.isPresent()) {
+            return potential.get();
+          }
         }
       }
     }
@@ -69,25 +57,25 @@ class LocalityBasedCandidateGenerator extends 
CandidateGenerator {
     // Compare locality gain/loss from swapping fromRegion with regions on 
toServer
     double fromRegionLocalityDelta = getWeightedLocality(cluster, fromRegion, 
toServer)
       - getWeightedLocality(cluster, fromRegion, fromServer);
-    for (int toRegionIndex : 
getRandomIterationOrder(cluster.regionsPerServer[toServer].length)) {
-      int toRegion = cluster.regionsPerServer[toServer][toRegionIndex];
-      double toRegionLocalityDelta = getWeightedLocality(cluster, toRegion, 
fromServer)
-        - getWeightedLocality(cluster, toRegion, toServer);
-      // If locality would remain neutral or improve, attempt the swap
-      if (fromRegionLocalityDelta + toRegionLocalityDelta >= 0) {
-        return Optional.of(getAction(fromServer, fromRegion, toServer, 
toRegion));
+    int toServertotalRegions =  cluster.regionsPerServer[toServer].length;
+    if (toServertotalRegions > 0) {
+      int startIndex = 
ThreadLocalRandom.current().nextInt(toServertotalRegions);
+      for (int i = 0; i < toServertotalRegions; i++) {
+        int toRegionIndex = (startIndex + i) % toServertotalRegions;
+        int toRegion = cluster.regionsPerServer[toServer][toRegionIndex];
+        double toRegionLocalityDelta = getWeightedLocality(cluster, toRegion, 
fromServer) -
+          getWeightedLocality(cluster, toRegion, toServer);
+        // If locality would remain neutral or improve, attempt the swap
+        if (fromRegionLocalityDelta + toRegionLocalityDelta >= 0) {
+          return Optional.of(getAction(fromServer, fromRegion, toServer, 
toRegion));
+        }
       }
     }
-    return Optional.absent();
+    return Optional.empty();
   }
 
   private double getWeightedLocality(BaseLoadBalancer.Cluster cluster, int 
region, int server) {
     return cluster.getOrComputeWeightedLocality(region, server,
       BaseLoadBalancer.Cluster.LocalityType.SERVER);
   }
-
-  void setServices(MasterServices services) {
-    this.masterServices = services;
-  }
-
 }
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.java
index 379fbe1..2882cdc 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.java
@@ -38,7 +38,6 @@ import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.BalancerDecision;
 import org.apache.hadoop.hbase.client.RegionInfo;
-import org.apache.hadoop.hbase.master.MasterServices;
 import org.apache.hadoop.hbase.master.RegionPlan;
 import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.Action;
 import 
org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.Action.Type;
@@ -187,7 +186,7 @@ public class StochasticLoadBalancer extends 
BaseLoadBalancer {
     numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, 
numRegionLoadsToRemember);
     minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, 
minCostNeedBalance);
     if (localityCandidateGenerator == null) {
-      localityCandidateGenerator = new 
LocalityBasedCandidateGenerator(services);
+      localityCandidateGenerator = new LocalityBasedCandidateGenerator();
     }
     localityCost = new ServerLocalityCostFunction(conf);
     rackLocalityCost = new RackLocalityCostFunction(conf);
@@ -308,17 +307,15 @@ public class StochasticLoadBalancer extends 
BaseLoadBalancer {
   }
 
   @Override
-  public synchronized void setMasterServices(MasterServices masterServices) {
-    super.setMasterServices(masterServices);
-    this.localityCandidateGenerator.setServices(masterServices);
-  }
-
-  @Override
   protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {
     regionReplicaHostCostFunction.init(c);
-    if (regionReplicaHostCostFunction.cost() > 0) return true;
+    if (regionReplicaHostCostFunction.cost() > 0) {
+      return true;
+    }
     regionReplicaRackCostFunction.init(c);
-    if (regionReplicaRackCostFunction.cost() > 0) return true;
+    if (regionReplicaRackCostFunction.cost() > 0) {
+      return true;
+    }
     return false;
   }
 

Reply via email to