Repository: hbase
Updated Branches:
  refs/heads/master b34ab5980 -> da68537ae


HBASE-17786 Create LoadBalancer perf-test tool to benchmark Load Balancer 
algorithm performance

Signed-off-by: Michael Stack <st...@apache.org>
Signed-off-by: Sean Busbey <bus...@apache.org>


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

Branch: refs/heads/master
Commit: da68537ae63ffbfc784de4dd6159d5d24f23f262
Parents: b34ab59
Author: Umesh Agashe <uaga...@cloudera.com>
Authored: Wed May 3 16:34:13 2017 -0700
Committer: Sean Busbey <bus...@apache.org>
Committed: Fri May 12 11:22:15 2017 -0500

----------------------------------------------------------------------
 .../hadoop/hbase/master/LoadBalancer.java       |   4 +-
 .../hbase/master/balancer/BaseLoadBalancer.java |   8 +-
 .../hbase/master/balancer/BalancerTestBase.java |  21 ---
 .../LoadBalancerPerformanceEvaluation.java      | 180 +++++++++++++++++++
 .../master/balancer/TestBaseLoadBalancer.java   |   7 +-
 .../TestFavoredStochasticLoadBalancer.java      |   1 -
 6 files changed, 187 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/da68537a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
index 01540b7..129fa7a 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
@@ -44,7 +44,7 @@ import edu.umd.cs.findbugs.annotations.Nullable;
  * <p>On cluster startup, bulk assignment can be used to determine
  * locations for all Regions in a cluster.
  *
- * <p>This classes produces plans for the
+ * <p>This class produces plans for the
  * {@link org.apache.hadoop.hbase.master.AssignmentManager}
  * to execute.
  */
@@ -52,7 +52,7 @@ import edu.umd.cs.findbugs.annotations.Nullable;
 public interface LoadBalancer extends Configurable, Stoppable, 
ConfigurationObserver {
 
   // Used to signal to the caller that the region(s) cannot be assigned
-  static final ServerName BOGUS_SERVER_NAME = 
ServerName.valueOf("bogus.example.com,1,1");
+  ServerName BOGUS_SERVER_NAME = ServerName.valueOf("bogus.example.com,1,1");
 
   /**
    * Set the current cluster status.  This allows a LoadBalancer to map host 
name to a server

http://git-wip-us.apache.org/repos/asf/hbase/blob/da68537a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
index 196e693..6410375 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
@@ -62,11 +62,9 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
 /**
- * The base class for load balancers. It provides the the functions used to by
- * {@link org.apache.hadoop.hbase.master.AssignmentManager} to assign regions
- * in the edge cases. It doesn't provide an implementation of the
- * actual balancing algorithm.
- *
+ * The base class for load balancers. It provides functions used by
+ * {@link org.apache.hadoop.hbase.master.AssignmentManager} to assign regions 
in the edge cases.
+ * It doesn't provide an implementation of the actual balancing algorithm.
  */
 public abstract class BaseLoadBalancer implements LoadBalancer {
   protected static final int MIN_SERVER_BALANCE = 2;

http://git-wip-us.apache.org/repos/asf/hbase/blob/da68537a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
index f93449c..de4a250 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -37,37 +36,17 @@ import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
-import com.google.protobuf.Service;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.ChoreService;
-import org.apache.hadoop.hbase.CoordinatedStateManager;
 import org.apache.hadoop.hbase.HBaseConfiguration;
-import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HRegionInfo;
-import org.apache.hadoop.hbase.HTableDescriptor;
-import org.apache.hadoop.hbase.NamespaceDescriptor;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.ServerName;
-import org.apache.hadoop.hbase.TableDescriptors;
 import org.apache.hadoop.hbase.TableName;
-import org.apache.hadoop.hbase.TableNotDisabledException;
-import org.apache.hadoop.hbase.TableNotFoundException;
-import org.apache.hadoop.hbase.client.ClusterConnection;
 import org.apache.hadoop.hbase.client.RegionReplicaUtil;
 import org.apache.hadoop.hbase.master.RackManager;
 import org.apache.hadoop.hbase.master.RegionPlan;
-import org.apache.hadoop.hbase.executor.ExecutorService;
-import org.apache.hadoop.hbase.master.*;
-import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
-import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
-import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
-import org.apache.hadoop.hbase.quotas.MasterQuotaManager;
-import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
-import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
 import org.apache.hadoop.net.DNSToSwitchMapping;
 import org.junit.Assert;
 import org.junit.BeforeClass;

http://git-wip-us.apache.org/repos/asf/hbase/blob/da68537a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/LoadBalancerPerformanceEvaluation.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/LoadBalancerPerformanceEvaluation.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/LoadBalancerPerformanceEvaluation.java
new file mode 100644
index 0000000..f174438
--- /dev/null
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/LoadBalancerPerformanceEvaluation.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.master.balancer;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Stopwatch;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
+import org.apache.hadoop.hbase.HBaseInterfaceAudience;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.classification.InterfaceAudience;
+import org.apache.hadoop.hbase.master.LoadBalancer;
+import org.apache.hadoop.hbase.util.AbstractHBaseTool;
+import org.apache.hadoop.hbase.util.Bytes;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Tool to test performance of different {@link 
org.apache.hadoop.hbase.master.LoadBalancer}
+ * implementations.
+ * Example command:
+ * $ bin/hbase 
org.apache.hadoop.hbase.master.balancer.LoadBalancerPerformanceEvaluation
+ *   -regions 1000 -servers 100
+ *   -load_balancer org.apache.hadoop.hbase.master.balancer.SimpleLoadBalancer
+ */
+@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS)
+public class LoadBalancerPerformanceEvaluation extends AbstractHBaseTool {
+  private static final Log LOG =
+      LogFactory.getLog(LoadBalancerPerformanceEvaluation.class.getName());
+
+  protected static final HBaseCommonTestingUtility UTIL = new 
HBaseCommonTestingUtility();
+
+  private static final int DEFAULT_NUM_REGIONS = 1000000;
+  private static Option NUM_REGIONS_OPT = new Option("regions", true,
+      "Number of regions to consider by load balancer. Default: " + 
DEFAULT_NUM_REGIONS);
+
+  private static final int DEFAULT_NUM_SERVERS = 1000;
+  private static Option NUM_SERVERS_OPT = new Option("servers", true,
+      "Number of servers to consider by load balancer. Default: " + 
DEFAULT_NUM_SERVERS);
+
+  private static final String DEFAULT_LOAD_BALANCER =
+      "org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer";
+  private static Option LOAD_BALANCER_OPT = new Option("load_balancer", true,
+      "Type of Load Balancer to use. Default: " + DEFAULT_LOAD_BALANCER);
+
+  private int numRegions;
+  private int numServers;
+  private String loadBalancerType;
+  private Class<?> loadBalancerClazz;
+
+  private LoadBalancer loadBalancer;
+
+  // data
+  private List<ServerName> servers;
+  private List<HRegionInfo> regions;
+  private Map<HRegionInfo, ServerName> regionServerMap;
+  private Map<ServerName, List<HRegionInfo>> serverRegionMap;
+
+  // Non-default configurations.
+  private void setupConf() {
+    conf.setClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, 
loadBalancerClazz, LoadBalancer.class);
+    loadBalancer = LoadBalancerFactory.getLoadBalancer(conf);
+  }
+
+  private void generateRegionsAndServers() {
+    // regions
+    regions = new ArrayList<>(numRegions);
+    regionServerMap = new HashMap<>(numRegions);
+    for (int i = 0; i < numRegions; ++i) {
+      byte[] start = new byte[16];
+      byte[] end = new byte[16];
+
+      Bytes.putInt(start, 0, i);
+      Bytes.putInt(end, 0, i + 1);
+      TableName tableName = TableName.valueOf("LoadBalancerPerfTable");
+      HRegionInfo hri = new HRegionInfo(tableName, start, end, false, i);
+      regions.add(hri);
+      regionServerMap.put(hri, null);
+    }
+
+    // servers
+    servers = new ArrayList<>(numServers);
+    serverRegionMap = new HashMap<>(numServers);
+    for (int i = 0; i < numServers; ++i) {
+      ServerName sn = ServerName.valueOf("srv" + i, 
HConstants.DEFAULT_REGIONSERVER_PORT, i);
+      servers.add(sn);
+      serverRegionMap.put(sn, i == 0 ? regions : Collections.emptyList());
+    }
+  }
+
+  @Override
+  protected void addOptions() {
+    addOption(NUM_REGIONS_OPT);
+    addOption(NUM_SERVERS_OPT);
+    addOption(LOAD_BALANCER_OPT);
+  }
+
+  @Override
+  protected void processOptions(CommandLine cmd) {
+    numRegions = getOptionAsInt(cmd, NUM_REGIONS_OPT.getOpt(), 
DEFAULT_NUM_REGIONS);
+    Preconditions.checkArgument(numRegions > 0, "Invalid number of regions!");
+
+    numServers = getOptionAsInt(cmd, NUM_SERVERS_OPT.getOpt(), 
DEFAULT_NUM_SERVERS);
+    Preconditions.checkArgument(numServers > 0, "Invalid number of servers!");
+
+    loadBalancerType = cmd.getOptionValue(LOAD_BALANCER_OPT.getOpt(), 
DEFAULT_LOAD_BALANCER);
+    Preconditions.checkArgument(!loadBalancerType.isEmpty(), "Invalid load 
balancer type!");
+
+    try {
+      loadBalancerClazz = Class.forName(loadBalancerType);
+    } catch (ClassNotFoundException e) {
+      System.err.println("Class '" + loadBalancerType + "' not found!");
+      System.exit(1);
+    }
+
+    setupConf();
+  }
+
+  private String formatResults(final String methodName, final long timeMillis) 
{
+    return String.format("Time for %-25s: %dms%n", methodName, timeMillis);
+  }
+
+  @Override
+  protected int doWork() throws Exception {
+    generateRegionsAndServers();
+
+    String methodName = "roundRobinAssignment";
+    LOG.info("Calling " + methodName);
+    Stopwatch watch = new Stopwatch().start();
+    loadBalancer.roundRobinAssignment(regions, servers);
+    System.out.print(formatResults(methodName, watch.elapsedMillis()));
+
+    methodName = "retainAssignment";
+    LOG.info("Calling " + methodName);
+    watch.reset().start();
+    loadBalancer.retainAssignment(regionServerMap, servers);
+    System.out.print(formatResults(methodName, watch.elapsedMillis()));
+
+    methodName = "balanceCluster";
+    LOG.info("Calling " + methodName);
+    watch.reset().start();
+    loadBalancer.balanceCluster(serverRegionMap);
+    System.out.print(formatResults(methodName, watch.elapsedMillis()));
+
+    return EXIT_SUCCESS;
+  }
+
+  public static void main(String[] args) throws IOException {
+    LoadBalancerPerformanceEvaluation tool = new 
LoadBalancerPerformanceEvaluation();
+    tool.setConf(UTIL.getConfiguration());
+    tool.run(args);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/da68537a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
index 751adc5..c43b94f 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
+import java.util.stream.Collectors;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -392,11 +393,7 @@ public class TestBaseLoadBalancer extends BalancerTestBase 
{
   }
 
   private List<ServerName> getListOfServerNames(final List<ServerAndLoad> 
sals) {
-    List<ServerName> list = new ArrayList<>();
-    for (ServerAndLoad e : sals) {
-      list.add(e.getServerName());
-    }
-    return list;
+    return 
sals.stream().map(ServerAndLoad::getServerName).collect(Collectors.toList());
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/hbase/blob/da68537a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticLoadBalancer.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticLoadBalancer.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticLoadBalancer.java
index 3138567..ca4337e 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticLoadBalancer.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticLoadBalancer.java
@@ -33,7 +33,6 @@ import java.util.Set;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.ClusterStatus;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;

Reply via email to