From f97e2d8d1952cd99a50b5ef0c66e72d9db462012 Mon Sep 17 00:00:00 2001 From: rajeshbabu Date: Wed, 18 Dec 2013 01:35:29 +0000 Subject: [PATCH] HBASE-10137 GeneralBulkAssigner with retain assignment plan can be used in EnableTableHandler to bulk assign the regions git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1551797 13f79535-47bb-0310-9956-ffa450edef68 --- .../hbase/master/AssignmentManager.java | 7 ++ .../hbase/master/GeneralBulkAssigner.java | 2 +- .../master/balancer/BaseLoadBalancer.java | 4 +- .../master/handler/EnableTableHandler.java | 96 ++++--------------- .../apache/hadoop/hbase/client/TestAdmin.java | 2 +- .../hbase/master/TestAssignmentManager.java | 12 +++ 6 files changed, 44 insertions(+), 79 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java index 93ca84dd2fd..b1a594d4604 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java @@ -3490,4 +3490,11 @@ public class AssignmentManager extends ZooKeeperListener { // remove the region plan as well just in case. clearRegionPlan(regionInfo); } + + /** + * @return Instance of load balancer + */ + public LoadBalancer getBalancer() { + return this.balancer; + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/GeneralBulkAssigner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/GeneralBulkAssigner.java index cfbcb6d6d2f..708e2002421 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/GeneralBulkAssigner.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/GeneralBulkAssigner.java @@ -53,7 +53,7 @@ public class GeneralBulkAssigner extends BulkAssigner { final AssignmentManager assignmentManager; final boolean waitTillAllAssigned; - GeneralBulkAssigner(final Server server, + public GeneralBulkAssigner(final Server server, final Map> bulkPlan, final AssignmentManager am, final boolean waitTillAllAssigned) { super(server); 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 667242e9b7a..710796be75a 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 @@ -559,7 +559,9 @@ public abstract class BaseLoadBalancer implements LoadBalancer { } else { // multiple new servers in the cluster on this same host int size = localServers.size(); - ServerName target = localServers.get(RANDOM.nextInt(size)); + ServerName target = + localServers.contains(oldServerName) ? oldServerName : localServers.get(RANDOM + .nextInt(size)); assignments.get(target).add(region); numRetainedAssigments++; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java index 11303c9ed3c..8ebcb470c8b 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java @@ -19,8 +19,9 @@ package org.apache.hadoop.hbase.master.handler; import java.io.IOException; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutorService; import org.apache.commons.logging.Log; @@ -38,9 +39,9 @@ import org.apache.hadoop.hbase.executor.EventHandler; import org.apache.hadoop.hbase.executor.EventType; import org.apache.hadoop.hbase.master.AssignmentManager; import org.apache.hadoop.hbase.master.BulkAssigner; +import org.apache.hadoop.hbase.master.GeneralBulkAssigner; import org.apache.hadoop.hbase.master.HMaster; import org.apache.hadoop.hbase.master.MasterCoprocessorHost; -import org.apache.hadoop.hbase.master.RegionPlan; import org.apache.hadoop.hbase.master.RegionStates; import org.apache.hadoop.hbase.master.ServerManager; import org.apache.hadoop.hbase.master.TableLockManager; @@ -173,22 +174,29 @@ public class EnableTableHandler extends EventHandler { // Set table enabling flag up in zk. this.assignmentManager.getZKTable().setEnablingTable(this.tableName); boolean done = false; + ServerManager serverManager = ((HMaster)this.server).getServerManager(); // Get the regions of this table. We're done when all listed // tables are onlined. List> tableRegionsAndLocations = MetaReader .getTableRegionsAndLocations(this.catalogTracker, tableName, true); int countOfRegionsInTable = tableRegionsAndLocations.size(); - List regions = regionsToAssignWithServerName(tableRegionsAndLocations); - int regionsCount = regions.size(); + Map regionsToAssign = + regionsToAssignWithServerName(tableRegionsAndLocations); + int regionsCount = regionsToAssign.size(); if (regionsCount == 0) { done = true; } LOG.info("Table '" + this.tableName + "' has " + countOfRegionsInTable + " regions, of which " + regionsCount + " are offline."); - BulkEnabler bd = new BulkEnabler(this.server, regions, countOfRegionsInTable, - true); + List onlineServers = serverManager.createDestinationServersList(); + Map> bulkPlan = + this.assignmentManager.getBalancer().retainAssignment(regionsToAssign, onlineServers); + LOG.info("Bulk assigning " + regionsCount + " region(s) across " + bulkPlan.size() + + " server(s), retainAssignment=true"); + + BulkAssigner ba = new GeneralBulkAssigner(this.server, bulkPlan, this.assignmentManager, true); try { - if (bd.bulkAssign()) { + if (ba.bulkAssign()) { done = true; } } catch (InterruptedException e) { @@ -214,19 +222,16 @@ public class EnableTableHandler extends EventHandler { * @return List of regions neither in transition nor assigned. * @throws IOException */ - private List regionsToAssignWithServerName( + private Map regionsToAssignWithServerName( final List> regionsInMeta) throws IOException { - ServerManager serverManager = ((HMaster) this.server).getServerManager(); - List regions = new ArrayList(); + Map regionsToAssign = + new HashMap(regionsInMeta.size()); RegionStates regionStates = this.assignmentManager.getRegionStates(); for (Pair regionLocation : regionsInMeta) { HRegionInfo hri = regionLocation.getFirst(); ServerName sn = regionLocation.getSecond(); if (regionStates.isRegionOffline(hri)) { - if (sn != null && serverManager.isServerOnline(sn)) { - this.assignmentManager.addPlan(hri.getEncodedName(), new RegionPlan(hri, null, sn)); - } - regions.add(hri); + regionsToAssign.put(hri, sn); } else { if (LOG.isDebugEnabled()) { LOG.debug("Skipping assign for the region " + hri + " during enable table " @@ -234,67 +239,6 @@ public class EnableTableHandler extends EventHandler { } } } - return regions; - } - - /** - * Run bulk enable. - */ - class BulkEnabler extends BulkAssigner { - private final List regions; - // Count of regions in table at time this assign was launched. - private final int countOfRegionsInTable; - - BulkEnabler(final Server server, final List regions, - final int countOfRegionsInTable, boolean retainAssignment) { - super(server); - this.regions = regions; - this.countOfRegionsInTable = countOfRegionsInTable; - } - - @Override - protected void populatePool(ExecutorService pool) throws IOException { - // In case of masterRestart always go with single assign. Going thro - // roundRobinAssignment will use bulkassign which may lead to double assignment. - for (HRegionInfo region : regions) { - if (assignmentManager.getRegionStates() - .isRegionInTransition(region)) { - continue; - } - final HRegionInfo hri = region; - pool.execute(Trace.wrap("BulkEnabler.populatePool",new Runnable() { - public void run() { - assignmentManager.assign(hri, true); - } - })); - } - } - - @Override - protected boolean waitUntilDone(long timeout) - throws InterruptedException { - long startTime = System.currentTimeMillis(); - long remaining = timeout; - List regions = null; - int lastNumberOfRegions = 0; - while (!server.isStopped() && remaining > 0) { - Thread.sleep(waitingTimeForEvents); - regions = assignmentManager.getRegionStates() - .getRegionsOfTable(tableName); - if (isDone(regions)) break; - - // Punt on the timeout as long we make progress - if (regions.size() > lastNumberOfRegions) { - lastNumberOfRegions = regions.size(); - timeout += waitingTimeForEvents; - } - remaining = timeout - (System.currentTimeMillis() - startTime); - } - return isDone(regions); - } - - private boolean isDone(final List regions) { - return regions != null && regions.size() >= this.countOfRegionsInTable; - } + return regionsToAssign; } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java index c010c228329..799606515d0 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java @@ -880,7 +880,7 @@ public class TestAdmin { for (Map.Entry entry : regions.entrySet()) { assertEquals(regions2.get(entry.getKey()), entry.getValue()); } - } + } /** * Multi-family scenario. Tests forcing split from client and diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java index bd3cdcb3b52..f4eb232cef4 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java @@ -1158,6 +1158,18 @@ public class TestAssignmentManager { } } + @Override + boolean assign(ServerName destination, List regions) { + if (enabling) { + for (HRegionInfo region : regions) { + assignmentCount++; + this.regionOnline(region, SERVERNAME_A); + } + return true; + } + return super.assign(destination, regions); + } + @Override public void assign(List regions) throws IOException, InterruptedException {