From hbase-commits-return-2449-apmail-hadoop-hbase-commits-archive=hadoop.apache.org@hadoop.apache.org Mon Dec 21 20:12:04 2009 Return-Path: Delivered-To: apmail-hadoop-hbase-commits-archive@minotaur.apache.org Received: (qmail 79400 invoked from network); 21 Dec 2009 20:12:04 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 21 Dec 2009 20:12:04 -0000 Received: (qmail 6827 invoked by uid 500); 21 Dec 2009 20:12:04 -0000 Delivered-To: apmail-hadoop-hbase-commits-archive@hadoop.apache.org Received: (qmail 6789 invoked by uid 500); 21 Dec 2009 20:12:03 -0000 Mailing-List: contact hbase-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: hbase-dev@hadoop.apache.org Delivered-To: mailing list hbase-commits@hadoop.apache.org Received: (qmail 6780 invoked by uid 99); 21 Dec 2009 20:12:03 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 21 Dec 2009 20:12:03 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 21 Dec 2009 20:11:54 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id E21E223889F7; Mon, 21 Dec 2009 20:11:32 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r892958 - in /hadoop/hbase/trunk: ./ src/java/org/apache/hadoop/hbase/client/ src/java/org/apache/hadoop/hbase/master/ src/test/org/apache/hadoop/hbase/ src/test/org/apache/hadoop/hbase/master/ Date: Mon, 21 Dec 2009 20:11:32 -0000 To: hbase-commits@hadoop.apache.org From: apurtell@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091221201132.E21E223889F7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: apurtell Date: Mon Dec 21 20:11:31 2009 New Revision: 892958 URL: http://svn.apache.org/viewvc?rev=892958&view=rev Log: HBASE-1982 [EC2] Handle potentially large and uneven instance startup times Added: hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/master/TestMinimumServerCount.java Modified: hadoop/hbase/trunk/CHANGES.txt hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HBaseAdmin.java hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnection.java hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/MiniHBaseCluster.java Modified: hadoop/hbase/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/CHANGES.txt?rev=892958&r1=892957&r2=892958&view=diff ============================================================================== --- hadoop/hbase/trunk/CHANGES.txt (original) +++ hadoop/hbase/trunk/CHANGES.txt Mon Dec 21 20:11:31 2009 @@ -247,6 +247,8 @@ Andrew Purtell) HBASE-2028 Add HTable.incrementColumnValue support to shell (Lars George via Andrew Purtell) + HBASE-1982 [EC2] Handle potentially large and uneven instance startup + times NEW FEATURES HBASE-1901 "General" partitioner for "hbase-48" bulk (behind the api, write Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HBaseAdmin.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HBaseAdmin.java?rev=892958&r1=892957&r2=892958&view=diff ============================================================================== --- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (original) +++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HBaseAdmin.java Mon Dec 21 20:11:31 2009 @@ -441,6 +441,24 @@ } /** + * @param tableName name of table to check + * @return true if all regions of the table are available + * @throws IOException + */ + public boolean isTableAvailable(byte[] tableName) throws IOException { + return connection.isTableAvailable(tableName); + } + + /** + * @param tableName name of table to check + * @return true if all regions of the table are available + * @throws IOException + */ + public boolean isTableAvailable(String tableName) throws IOException { + return connection.isTableAvailable(Bytes.toBytes(tableName)); + } + + /** * Add a column to an existing table. * Asynchronous operation. * Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnection.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnection.java?rev=892958&r1=892957&r2=892958&view=diff ============================================================================== --- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnection.java (original) +++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnection.java Mon Dec 21 20:11:31 2009 @@ -77,7 +77,14 @@ * @throws IOException */ public boolean isTableDisabled(byte[] tableName) throws IOException; - + + /** + * @param tableName + * @return true if all regions of the table are available, false otherwise + * @throws IOException + */ + public boolean isTableAvailable(byte[] tableName) throws IOException; + /** * List all the userspace tables. In other words, scan the META table. * Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java?rev=892958&r1=892957&r2=892958&view=diff ============================================================================== --- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java (original) +++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java Mon Dec 21 20:11:31 2009 @@ -29,6 +29,7 @@ import java.util.Map; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -463,6 +464,29 @@ return testTableOnlineState(tableName, false); } + public boolean isTableAvailable(final byte[] tableName) throws IOException { + final AtomicBoolean available = new AtomicBoolean(true); + MetaScannerVisitor visitor = new MetaScannerVisitor() { + @Override + public boolean processRow(Result row) throws IOException { + byte[] value = row.getValue(CATALOG_FAMILY, REGIONINFO_QUALIFIER); + HRegionInfo info = Writables.getHRegionInfoOrNull(value); + if (info != null) { + if (Bytes.equals(tableName, info.getTableDesc().getName())) { + value = row.getValue(CATALOG_FAMILY, SERVER_QUALIFIER); + if (value == null) { + available.set(false); + return false; + } + } + } + return true; + } + }; + MetaScanner.metaScan(conf, visitor); + return available.get(); + } + /* * If online == true * Returns true if all regions are online Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java?rev=892958&r1=892957&r2=892958&view=diff ============================================================================== --- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java (original) +++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java Mon Dec 21 20:11:31 2009 @@ -752,6 +752,9 @@ if (!this.regionManager.areAllMetaRegionsOnline()) { throw new NotAllMetaRegionsOnlineException(); } + if (!this.serverManager.canAssignUserRegions()) { + throw new IOException("not enough servers to create table yet"); + } createTable(newRegion); LOG.info("created table " + desc.getNameAsString()); break; @@ -1155,9 +1158,11 @@ } private static void printUsageAndExit() { - System.err.println("Usage: Master start|stop"); + System.err.println("Usage: Master [opts] start|stop"); System.err.println(" start Start Master. If local mode, start Master and RegionServer in same JVM"); System.err.println(" stop Start cluster shutdown; Master signals RegionServer shutdown"); + System.err.println(" where [opts] are:"); + System.err.println(" --minServers= Minimum RegionServers needed to host user tables."); System.exit(0); } @@ -1168,6 +1173,13 @@ HBaseConfiguration conf = new HBaseConfiguration(); // Process command-line args. for (String cmd: args) { + + if (cmd.startsWith("--minServers=")) { + conf.setInt("hbase.regions.server.count.min", + Integer.valueOf(cmd.substring(13))); + continue; + } + if (cmd.equalsIgnoreCase("start")) { try { // Print out vm stats before starting up. Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java?rev=892958&r1=892957&r2=892958&view=diff ============================================================================== --- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java (original) +++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java Mon Dec 21 20:11:31 2009 @@ -56,7 +56,6 @@ import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.util.Threads; import org.apache.hadoop.hbase.util.Writables; -import org.apache.hadoop.hbase.zookeeper.ZooKeeperWrapper; /** * Class to manage assigning regions to servers, state of root and meta, etc. @@ -414,6 +413,12 @@ // and are on-line continue; } + if (!i.isMetaRegion() && + !master.getServerManager().canAssignUserRegions()) { + LOG.debug("user region " + i.getRegionNameAsString() + + " is in transition but not enough servers yet"); + continue; + } if (s.isUnassigned()) { regionsToAssign.add(s); } Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java?rev=892958&r1=892957&r2=892958&view=diff ============================================================================== --- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java (original) +++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java Mon Dec 21 20:11:31 2009 @@ -93,6 +93,8 @@ private final ServerMonitor serverMonitorThread; + private int minimumServerCount; + /* * Dumps into log current stats on dead servers and number of servers * TODO: Make this a metric; dump metrics into log. @@ -136,6 +138,7 @@ this.nobalancingCount = c.getInt("hbase.regions.nobalancing.count", 4); int metaRescanInterval = c.getInt("hbase.master.meta.thread.rescanfrequency", 60 * 1000); + this.minimumServerCount = c.getInt("hbase.regions.server.count.min", 0); this.serverMonitorThread = new ServerMonitor(metaRescanInterval, this.master.getShutdownRequested()); this.serverMonitorThread.start(); @@ -844,4 +847,16 @@ m.putAll(this.loadToServers.headMap(l)); } } + + public boolean canAssignUserRegions() { + if (minimumServerCount == 0) { + return true; + } + return (numServers() >= minimumServerCount); + } + + public void setMinimumServerCount(int minimumServerCount) { + this.minimumServerCount = minimumServerCount; + } + } Modified: hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/MiniHBaseCluster.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/MiniHBaseCluster.java?rev=892958&r1=892957&r2=892958&view=diff ============================================================================== --- hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/MiniHBaseCluster.java (original) +++ hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/MiniHBaseCluster.java Mon Dec 21 20:11:31 2009 @@ -41,7 +41,7 @@ public class MiniHBaseCluster implements HConstants { static final Log LOG = LogFactory.getLog(MiniHBaseCluster.class.getName()); private HBaseConfiguration conf; - private LocalHBaseCluster hbaseCluster; + public LocalHBaseCluster hbaseCluster; /** * Start a MiniHBaseCluster. Added: hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/master/TestMinimumServerCount.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/master/TestMinimumServerCount.java?rev=892958&view=auto ============================================================================== --- hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/master/TestMinimumServerCount.java (added) +++ hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/master/TestMinimumServerCount.java Mon Dec 21 20:11:31 2009 @@ -0,0 +1,68 @@ +package org.apache.hadoop.hbase.master; + +import java.io.IOException; + +import org.apache.hadoop.hbase.HBaseClusterTestCase; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.apache.hadoop.hbase.client.HTable; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; + +public class TestMinimumServerCount extends HBaseClusterTestCase { + + static final String TABLE_NAME = "TestTable"; + + public TestMinimumServerCount() { + // start cluster with one region server only + super(1, true); + } + + boolean isTableAvailable(String tableName) throws IOException { + boolean available = true; + HTable meta = new HTable(conf, ".META."); + ResultScanner scanner = meta.getScanner(HConstants.CATALOG_FAMILY); + Result result; + while ((result = scanner.next()) != null) { + // set available to false if a region of the table is found with no + // assigned server + byte[] value = result.getValue(HConstants.CATALOG_FAMILY, + HConstants.SERVER_QUALIFIER); + if (value == null) { + available = false; + break; + } + } + return available; + } + + public void testMinimumServerCount() throws Exception { + HBaseAdmin admin = new HBaseAdmin(conf); + + // create and disable table + admin.createTable(createTableDescriptor(TABLE_NAME)); + admin.disableTable(TABLE_NAME); + assertFalse(admin.isTableEnabled(TABLE_NAME)); + + // reach in and set minimum server count + cluster.hbaseCluster.getMaster().getServerManager() + .setMinimumServerCount(2); + + // now try to enable the table + try { + admin.enableTable(TABLE_NAME); + } catch (IOException ex) { + // ignore + } + Thread.sleep(10 * 1000); + assertFalse(admin.isTableAvailable(TABLE_NAME)); + + // now start another region server + cluster.startRegionServer(); + + // sleep a bit for assignment + Thread.sleep(10 * 1000); + assertTrue(admin.isTableAvailable(TABLE_NAME)); + } + +}