You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by li...@apache.org on 2017/03/21 10:08:30 UTC

hbase git commit: HBASE-17060 backport HBASE-16570 (Compute region locality in parallel at startup) to 1.3.1

Repository: hbase
Updated Branches:
  refs/heads/branch-1.3 446a21fed -> 693b51d81


HBASE-17060 backport HBASE-16570 (Compute region locality in parallel at startup) to 1.3.1


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

Branch: refs/heads/branch-1.3
Commit: 693b51d81af0c446b305af69fe130faee07581a6
Parents: 446a21f
Author: Yu Li <li...@apache.org>
Authored: Tue Mar 21 15:14:31 2017 +0800
Committer: Yu Li <li...@apache.org>
Committed: Tue Mar 21 15:14:31 2017 +0800

----------------------------------------------------------------------
 .../hbase/master/balancer/BaseLoadBalancer.java | 11 +++--
 .../master/balancer/RegionLocationFinder.java   | 47 ++++++++++++++++++--
 .../balancer/TestRegionLocationFinder.java      | 21 +++++++++
 3 files changed, 71 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/693b51d8/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 c2529a8..2df4fbe 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
@@ -1231,7 +1231,7 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
       return assignments;
     }
 
-    Cluster cluster = createCluster(servers, regions);
+    Cluster cluster = createCluster(servers, regions, false);
     List<HRegionInfo> unassignedRegions = new ArrayList<HRegionInfo>();
 
     roundRobinAssignment(cluster, regions, unassignedRegions,
@@ -1278,7 +1278,10 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
   }
 
   protected Cluster createCluster(List<ServerName> servers,
-      Collection<HRegionInfo> regions) {
+      Collection<HRegionInfo> regions, boolean forceRefresh) {
+    if (forceRefresh) {
+      regionFinder.refreshAndWait(regions);
+    }
     // Get the snapshot of the current assignments for the regions in question, and then create
     // a cluster out of it. Note that we might have replicas already assigned to some servers
     // earlier. So we want to get the snapshot to see those assignments, but this will only contain
@@ -1352,7 +1355,7 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
     }
 
     List<HRegionInfo> regions = Lists.newArrayList(regionInfo);
-    Cluster cluster = createCluster(servers, regions);
+    Cluster cluster = createCluster(servers, regions, false);
     return randomAssignment(cluster, regionInfo, servers);
   }
 
@@ -1427,7 +1430,7 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
     int numRandomAssignments = 0;
     int numRetainedAssigments = 0;
 
-    Cluster cluster = createCluster(servers, regions.keySet());
+    Cluster cluster = createCluster(servers, regions.keySet(), true);
 
     for (Map.Entry<HRegionInfo, ServerName> entry : regions.entrySet()) {
       HRegionInfo region = entry.getKey();

http://git-wip-us.apache.org/repos/asf/hbase/blob/693b51d8/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java
index a6724ee..6c5cb19 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java
@@ -21,6 +21,7 @@ import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
@@ -63,11 +64,13 @@ import java.util.concurrent.TimeUnit;
 class RegionLocationFinder {
   private static final Log LOG = LogFactory.getLog(RegionLocationFinder.class);
   private static final long CACHE_TIME = 240 * 60 * 1000;
+  private static final HDFSBlocksDistribution EMPTY_BLOCK_DISTRIBUTION = new HDFSBlocksDistribution();
   private Configuration conf;
   private volatile ClusterStatus status;
   private MasterServices services;
   private final ListeningExecutorService executor;
-  private long lastFullRefresh = 0;
+  // Do not scheduleFullRefresh at master startup
+  private long lastFullRefresh = EnvironmentEdgeManager.currentTime();
 
   private CacheLoader<HRegionInfo, HDFSBlocksDistribution> loader =
       new CacheLoader<HRegionInfo, HDFSBlocksDistribution>() {
@@ -165,8 +168,7 @@ class RegionLocationFinder {
   }
 
   protected List<ServerName> getTopBlockLocations(HRegionInfo region) {
-    HDFSBlocksDistribution blocksDistribution = getBlockDistribution(region);
-    List<String> topHosts = blocksDistribution.getTopHosts();
+    List<String> topHosts = getBlockDistribution(region).getTopHosts();
     return mapHostNameToServerName(topHosts);
   }
 
@@ -208,7 +210,7 @@ class RegionLocationFinder {
           + region.getEncodedName(), ioe);
     }
 
-    return new HDFSBlocksDistribution();
+    return EMPTY_BLOCK_DISTRIBUTION;
   }
 
   /**
@@ -295,4 +297,41 @@ class RegionLocationFinder {
       return blockDistbn;
     }
   }
+
+  private ListenableFuture<HDFSBlocksDistribution> asyncGetBlockDistribution(
+      HRegionInfo hri) {
+    try {
+      return loader.reload(hri, EMPTY_BLOCK_DISTRIBUTION);
+    } catch (Exception e) {
+      return Futures.immediateFuture(EMPTY_BLOCK_DISTRIBUTION);
+    }
+  }
+
+  public void refreshAndWait(Collection<HRegionInfo> hris) {
+    ArrayList<ListenableFuture<HDFSBlocksDistribution>> regionLocationFutures =
+        new ArrayList<ListenableFuture<HDFSBlocksDistribution>>(hris.size());
+    for (HRegionInfo hregionInfo : hris) {
+      regionLocationFutures.add(asyncGetBlockDistribution(hregionInfo));
+    }
+    int index = 0;
+    for (HRegionInfo hregionInfo : hris) {
+      ListenableFuture<HDFSBlocksDistribution> future = regionLocationFutures
+          .get(index);
+      try {
+        cache.put(hregionInfo, future.get());
+      } catch (InterruptedException ite) {
+        Thread.currentThread().interrupt();
+      } catch (ExecutionException ee) {
+        LOG.debug(
+            "ExecutionException during HDFSBlocksDistribution computation. for region = "
+                + hregionInfo.getEncodedName(), ee);
+      }
+      index++;
+    }
+  }
+
+  // For test
+  LoadingCache<HRegionInfo, HDFSBlocksDistribution> getCache() {
+    return cache;
+  }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/693b51d8/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionLocationFinder.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionLocationFinder.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionLocationFinder.java
index bdbdc9f..2585a87 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionLocationFinder.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionLocationFinder.java
@@ -18,6 +18,7 @@
 package org.apache.hadoop.hbase.master.balancer;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
@@ -141,4 +142,24 @@ public class TestRegionLocationFinder {
       }
     }
   }
+
+  @Test
+  public void testRefreshAndWait() throws Exception {
+    finder.getCache().invalidateAll();
+    for (int i = 0; i < ServerNum; i++) {
+      HRegionServer server = cluster.getRegionServer(i);
+      List<Region> regions = server.getOnlineRegions(tableName);
+      if (regions.size() <= 0) {
+        continue;
+      }
+      List<HRegionInfo> regionInfos = new ArrayList<HRegionInfo>(regions.size());
+      for (Region region : regions) {
+        regionInfos.add(region.getRegionInfo());
+      }
+      finder.refreshAndWait(regionInfos);
+      for (HRegionInfo regionInfo : regionInfos) {
+        assertNotNull(finder.getCache().getIfPresent(regionInfo));
+      }
+    }
+  }
 }