From face3d53ce24a50e25c9708bcc8a940c891cafc7 Mon Sep 17 00:00:00 2001 From: Artem Ervits Date: Tue, 27 Nov 2018 18:58:24 -0500 Subject: [PATCH] HBASE-18735 Provide a fast mechanism for shutting down mini cluster --- .../apache/hadoop/hbase/HBaseTestingUtility.java | 42 +++++++++++---- .../org/apache/hadoop/hbase/MiniHBaseCluster.java | 19 +++++-- .../hadoop/hbase/TestHBaseTestingUtility.java | 59 ++++++++++++++++++++-- 3 files changed, 102 insertions(+), 18 deletions(-) diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java index 655bbdbe01..9d9fc48338 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java @@ -1240,17 +1240,7 @@ public class HBaseTestingUtility extends HBaseZKTestingUtility { * Shutdown HBase mini cluster. Does not shutdown zk or dfs if running. */ public void shutdownMiniHBaseCluster() throws IOException { - if (hbaseAdmin != null) { - hbaseAdmin.close(); - hbaseAdmin = null; - } - if (this.connection != null) { - this.connection.close(); - this.connection = null; - } - // unset the configuration for MIN and MAX RS to start - conf.setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, -1); - conf.setInt(ServerManager.WAIT_ON_REGIONSERVERS_MAXTOSTART, -1); + cleanup(); if (this.hbaseCluster != null) { this.hbaseCluster.shutdown(); // Wait till hbase is down before going on to shutdown zk. @@ -1263,6 +1253,36 @@ public class HBaseTestingUtility extends HBaseZKTestingUtility { } } + /** + * Abruptly Shutdown HBase mini cluster. Does not shutdown zk or dfs if running. + */ + public void forceShutdownMiniHBaseCluster() throws IOException { + cleanup(); + if (this.hbaseCluster != null) { + getMiniHBaseCluster().killAll(); + this.hbaseCluster = null; + } + if (zooKeeperWatcher != null) { + zooKeeperWatcher.close(); + zooKeeperWatcher = null; + } + } + + // close hbase admin, close current connection and reset MIN MAX configs for RS. + private void cleanup() throws IOException { + if (hbaseAdmin != null) { + hbaseAdmin.close(); + hbaseAdmin = null; + } + if (this.connection != null) { + this.connection.close(); + this.connection = null; + } + // unset the configuration for MIN and MAX RS to start + conf.setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, -1); + conf.setInt(ServerManager.WAIT_ON_REGIONSERVERS_MAXTOSTART, -1); + } + /** * Returns the path to the default root dir the minicluster uses. If create * is true, a new root directory path is fetched irrespective of whether it has been fetched diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java hbase-server/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java index 473eb74abf..15a688bcfa 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java @@ -49,7 +49,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProto /** * This class creates a single process HBase cluster. - * each server. The master uses the 'default' FileSystem. The RegionServers, + * The master uses the 'default' FileSystem. The RegionServers, * if we are running on DistributedFilesystem, create a FileSystem instance * each and will close down their instance on the way out. */ @@ -87,6 +87,8 @@ public class MiniHBaseCluster extends HBaseCluster { * @param conf Configuration to be used for cluster * @param numMasters initial number of masters to start. * @param numRegionServers initial number of region servers to start. + * @param masterClass master class + * @param regionserverClass RegionServer class */ public MiniHBaseCluster(Configuration conf, int numMasters, int numRegionServers, Class masterClass, @@ -96,10 +98,15 @@ public class MiniHBaseCluster extends HBaseCluster { } /** + * @param conf Configuration to be used for cluster + * @param numMasters initial number of masters to start. * @param rsPorts Ports that RegionServer should use; pass ports if you want to test cluster * restart where for sure the regionservers come up on same address+port (but * just with different startcode); by default mini hbase clusters choose new * arbitrary ports on each cluster start. + * @param numRegionServers initial number of region servers to start. + * @param masterClass master class + * @param regionserverClass RegionServer class * @throws IOException * @throws InterruptedException */ @@ -419,10 +426,11 @@ public class MiniHBaseCluster extends HBaseCluster { } /** - * Starts a region server thread and waits until its processed by master. Throws an exception + * Starts a region server thread and waits until its processed by master.Throws an exception * when it can't start a region server or when the region server is not processed by master * within the timeout. * + * @param timeout timeout for waiting * @return New RegionServerThread */ public JVMClusterUtil.RegionServerThread startRegionServerAndWait(long timeout) @@ -449,6 +457,7 @@ public class MiniHBaseCluster extends HBaseCluster { /** * Cause a region server to exit doing basic clean up only on its way out. * @param serverNumber Used as index into a list. + * @return server regionserver to abort */ public String abortRegionServer(int serverNumber) { HRegionServer server = getRegionServer(serverNumber); @@ -558,6 +567,7 @@ public class MiniHBaseCluster extends HBaseCluster { /** * Cause a master to exit without shutting down entire cluster. * @param serverNumber Used as index into a list. + * @return server master to abort */ public String abortMaster(int serverNumber) { HMaster server = getMaster(serverNumber); @@ -611,7 +621,6 @@ public class MiniHBaseCluster extends HBaseCluster { * * @return true if an active master becomes available. false if there are no * masters left. - * @throws InterruptedException */ @Override public boolean waitForActiveAndReadyMaster(long timeout) throws IOException { @@ -705,6 +714,7 @@ public class MiniHBaseCluster extends HBaseCluster { /** * Call flushCache on all regions of the specified table. + * @param tableName table to flushCache on. */ public void flushcache(TableName tableName) throws IOException { for (JVMClusterUtil.RegionServerThread t : this.hbaseCluster.getRegionServers()) { @@ -718,6 +728,7 @@ public class MiniHBaseCluster extends HBaseCluster { /** * Call flushCache on all regions on all participating regionservers. + * @param major compaction * @throws IOException */ public void compact(boolean major) throws IOException { @@ -731,6 +742,8 @@ public class MiniHBaseCluster extends HBaseCluster { /** * Call flushCache on all regions of the specified table. + * @param tableName table to compact + * @param major compaction * @throws IOException */ public void compact(TableName tableName, boolean major) throws IOException { diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/TestHBaseTestingUtility.java hbase-server/src/test/java/org/apache/hadoop/hbase/TestHBaseTestingUtility.java index 97de8a9e77..b121b1fb34 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/TestHBaseTestingUtility.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/TestHBaseTestingUtility.java @@ -26,11 +26,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.File; -import java.io.IOException; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Random; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; @@ -62,6 +58,9 @@ import org.slf4j.LoggerFactory; */ @Category({MiscTests.class, LargeTests.class}) public class TestHBaseTestingUtility { + private static final int NUMTABLES = 100; + private static final int NUMROWS = 1000; + private static final int NUMREGIONS = 10; @ClassRule public static final HBaseClassTestRule CLASS_RULE = @@ -471,4 +470,56 @@ public class TestHBaseTestingUtility { htu.shutdownMiniCluster(); } } + + @Test + public void testShutdownHBaseMiniCluster() throws Exception { + + HBaseTestingUtility htu = new HBaseTestingUtility(); + htu.startMiniZKCluster(); + + try { + htu.startMiniHBaseCluster(); + + TableName tableName; + byte[] FAM_NAME; + + for(int i = 0; i < NUMTABLES; i++) { + tableName = TableName.valueOf(name.getMethodName() + i); + FAM_NAME = Bytes.toBytes("fam" + i); + + try (Table table = htu.createMultiRegionTable(tableName, FAM_NAME, NUMREGIONS)) { + htu.loadRandomRows(table, FAM_NAME, 100, NUMROWS); + } + } + } finally { + htu.shutdownMiniHBaseCluster(); + htu.shutdownMiniZKCluster(); + } + } + + @Test + public void testForceShutdownHBaseMiniCluster() throws Exception { + + HBaseTestingUtility htu = new HBaseTestingUtility(); + htu.startMiniZKCluster(); + + try { + htu.startMiniHBaseCluster(); + + TableName tableName; + byte[] FAM_NAME; + + for(int i = 0; i < NUMTABLES; i++) { + tableName = TableName.valueOf(name.getMethodName() + i); + FAM_NAME = Bytes.toBytes("fam" + i); + + try (Table table = htu.createMultiRegionTable(tableName, FAM_NAME, NUMREGIONS)) { + htu.loadRandomRows(table, FAM_NAME, 100, NUMROWS); + } + } + } finally { + htu.forceShutdownMiniHBaseCluster(); + htu.shutdownMiniZKCluster(); + } + } } -- 2.16.2