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 2014/02/11 19:28:32 UTC
svn commit: r1567267 - in /hbase/branches/0.89-fb/src:
main/java/org/apache/hadoop/hbase/client/
main/java/org/apache/hadoop/hbase/ipc/
main/java/org/apache/hadoop/hbase/master/ test/java/org/apache/hadoop/hbase/
test/java/org/apache/hadoop/hbase/client/
Author: liyin
Date: Tue Feb 11 18:28:31 2014
New Revision: 1567267
URL: http://svn.apache.org/r1567267
Log:
[0.89-fb][HBASE-10425] Hacky way to create a table on specified subset of machines
Author: adela
Summary: should not affect existing code
Test Plan: added unit test: TestHackyCreateTable; ran TestAdmin too - nothing is ruined
Reviewers: liyintang, manukranthk, aaiyer, gauravm
Reviewed By: liyintang
CC: hbase-eng@
Differential Revision: https://phabricator.fb.com/D1151470
Task ID: 3610285
Added:
hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestHackyCreateTable.java
Modified:
hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java
hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/RegionPlacement.java
hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java
hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java?rev=1567267&r1=1567266&r2=1567267&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java Tue Feb 11 18:28:31 2014
@@ -265,18 +265,27 @@ public class HBaseAdmin {
public void createTable(final HTableDescriptor desc, byte [][] splitKeys)
throws IOException {
HTableDescriptor.isLegalTableName(desc.getName());
- if(splitKeys != null && splitKeys.length > 1) {
- Arrays.sort(splitKeys, Bytes.BYTES_COMPARATOR);
- // Verify there are no duplicate split keys
- byte [] lastKey = null;
- for(byte [] splitKey : splitKeys) {
- if(lastKey != null && Bytes.equals(splitKey, lastKey)) {
- throw new IllegalArgumentException("All split keys must be unique, found duplicate");
- }
- lastKey = splitKey;
- }
- }
+ checkSplitKeys(splitKeys);
createTableAsync(desc, splitKeys);
+ checkTableOnline(desc, splitKeys);
+ }
+
+ /**
+ * Same like {@link #createTable(HTableDescriptor, byte[][])} but creates
+ * table on specific regionservers
+ *
+ * @throws IOException
+ */
+ public void createTable(final HTableDescriptor desc, byte[][] splitKeys,
+ List<HServerAddress> servers) throws IOException {
+ HTableDescriptor.isLegalTableName(desc.getName());
+ checkSplitKeys(splitKeys);
+ createTableAsyncAndPlaceOnServers(desc, splitKeys, servers);
+ checkTableOnline(desc, splitKeys);
+ }
+
+ private void checkTableOnline(final HTableDescriptor desc, byte[][] splitKeys)
+ throws IOException, RegionOfflineException, InterruptedIOException {
int numRegs = splitKeys == null ? 1 : splitKeys.length + 1;
int prevRegCount = 0;
for (int tries = 0; tries < numRetries; ++tries) {
@@ -327,6 +336,21 @@ public class HBaseAdmin {
}
}
+ public void checkSplitKeys(byte[][] splitKeys) {
+ if (splitKeys != null && splitKeys.length > 1) {
+ Arrays.sort(splitKeys, Bytes.BYTES_COMPARATOR);
+ // Verify there are no duplicate split keys
+ byte[] lastKey = null;
+ for (byte[] splitKey : splitKeys) {
+ if (lastKey != null && Bytes.equals(splitKey, lastKey)) {
+ throw new IllegalArgumentException(
+ "All split keys must be unique, found duplicate");
+ }
+ lastKey = splitKey;
+ }
+ }
+ }
+
/**
* Creates a new table but does not block and wait for it to come online.
* Asynchronous operation.
@@ -356,6 +380,31 @@ public class HBaseAdmin {
}
/**
+ * SAme as {@link #createTableAsync(HTableDescriptor, byte[][])} but using a
+ * specific set of servers to assign the regions
+ *
+ * @param desc
+ * @param splitKeys
+ * @param servers
+ * @throws IOException
+ */
+ public void createTableAsyncAndPlaceOnServers(HTableDescriptor desc,
+ byte[][] splitKeys, List<HServerAddress> servers) throws IOException {
+ if (this.master == null) {
+ throw new MasterNotRunningException("master has been shut down");
+ }
+ HTableDescriptor.isLegalTableName(desc.getName());
+ try {
+ this.master.createTableAndAssignOnServers(desc, splitKeys, servers);
+ } catch (RemoteException e) {
+ throw RemoteExceptionHandler.decodeRemoteException(e);
+ } catch (SocketTimeoutException ste) {
+ LOG.warn("Creating " + desc.getNameAsString() + " took too long", ste);
+ }
+ }
+
+
+ /**
* Deletes a table.
* Synchronous operation.
*
Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java?rev=1567267&r1=1567266&r2=1567267&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java Tue Feb 11 18:28:31 2014
@@ -26,6 +26,7 @@ import org.apache.hadoop.hbase.ClusterSt
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HServerAddress;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.io.Writable;
@@ -58,6 +59,17 @@ public interface HMasterInterface extend
throws IOException;
/**
+ * Same like {@link #createTable(HTableDescriptor, byte[][])} above, but we
+ * specify the set of machines where we want the regions to be assigned
+ *
+ * @param desc
+ * @param splitKeys
+ * @throws IOException
+ */
+ public void createTableAndAssignOnServers(HTableDescriptor desc,
+ byte[][] splitKeys, List<HServerAddress> servers) throws IOException;
+
+ /**
* Deletes a table
* @param tableName table to delete
* @throws IOException e
Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/HMaster.java?rev=1567267&r1=1567266&r2=1567267&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/HMaster.java Tue Feb 11 18:28:31 2014
@@ -1413,26 +1413,41 @@ public class HMaster extends HasThread i
}
}
- @Override
- public void createTable(HTableDescriptor desc, byte [][] splitKeys)
- throws IOException {
+ /**
+ * Creates regionInfo for the new regions that are going to be part of the new
+ * table
+ *
+ * @param desc - descriptor of the new table
+ * @param splitKeys - split keys marking the start and end key for every region
+ * @return array of new HRegionInfo
+ * @throws IOException
+ */
+ public HRegionInfo[] createRegionsForNewTable(HTableDescriptor desc,
+ byte[][] splitKeys) throws IOException {
if (!isMasterRunning()) {
throw new MasterNotRunningException();
}
- HRegionInfo [] newRegions = null;
- if(splitKeys == null || splitKeys.length == 0) {
- newRegions = new HRegionInfo [] { new HRegionInfo(desc, null, null) };
+ HRegionInfo[] newRegions = null;
+ if (splitKeys == null || splitKeys.length == 0) {
+ newRegions = new HRegionInfo[] { new HRegionInfo(desc, null, null) };
} else {
int numRegions = splitKeys.length + 1;
newRegions = new HRegionInfo[numRegions];
- byte [] startKey = null;
- byte [] endKey = null;
- for(int i=0;i<numRegions;i++) {
+ byte[] startKey = null;
+ byte[] endKey = null;
+ for (int i = 0; i < numRegions; i++) {
endKey = (i == splitKeys.length) ? null : splitKeys[i];
newRegions[i] = new HRegionInfo(desc, startKey, endKey);
startKey = endKey;
}
}
+ return newRegions;
+ }
+
+ @Override
+ public void createTable(HTableDescriptor desc, byte [][] splitKeys)
+ throws IOException {
+ HRegionInfo[] newRegions = createRegionsForNewTable(desc, splitKeys);
try {
// We can not create a table unless meta regions have already been
// assigned and scanned.
@@ -1453,6 +1468,31 @@ public class HMaster extends HasThread i
}
}
+ @Override
+ public void createTableAndAssignOnServers(HTableDescriptor desc,
+ byte[][] splitKeys, List<HServerAddress> servers) throws IOException {
+ HRegionInfo[] newRegions = createRegionsForNewTable(desc, splitKeys);
+ try {
+ // We can not create a table unless meta regions have already been
+ // assigned and scanned.
+ if (!this.regionManager.areAllMetaRegionsOnline()) {
+ throw new NotAllMetaRegionsOnlineException();
+ }
+ if (!this.serverManager.hasEnoughRegionServers()) {
+ throw new IOException("not enough servers to create table yet");
+ }
+ createTable(newRegions, servers);
+ LOG.info("Succeeded in creating table " + desc.getNameAsString()
+ + "on the specified servers");
+ } catch (TableExistsException e) {
+ throw e;
+ } catch (IOException e) {
+ LOG.error("Cannot create table " + desc.getNameAsString()
+ + " because of " + e.toString() + " on the specified servers");
+ throw RemoteExceptionHandler.checkIOException(e);
+ }
+ }
+
private static boolean tableExists(HRegionInterface srvr,
byte[] metaRegionName, String tableName)
throws IOException {
@@ -1477,8 +1517,39 @@ public class HMaster extends HasThread i
return false;
}
- private synchronized void createTable(final HRegionInfo [] newRegions)
- throws IOException {
+ private synchronized void createTable(final HRegionInfo[] newRegions)
+ throws IOException {
+ String tableName = newRegions[0].getTableDesc().getNameAsString();
+ AssignmentPlan assignmentPlan = null;
+ if (this.shouldAssignRegionsWithFavoredNodes) {
+ // Get the assignment domain for this table
+ AssignmentDomain domain = this.getAssignmentDomain(tableName);
+ // Get the assignment plan for the new regions
+ assignmentPlan = regionPlacement.getNewAssignmentPlan(newRegions, domain);
+ }
+ createTable(newRegions, assignmentPlan);
+ }
+
+ /**
+ * Create table such that we place the new regions on the specified machines
+ * @param newRegions - new regions from the new table
+ * @param servers - set of machines where we like the regions to be placed
+ * @throws IOException
+ */
+ private synchronized void createTable(final HRegionInfo[] newRegions,
+ List<HServerAddress> servers) throws IOException {
+ String tableName = newRegions[0].getTableDesc().getNameAsString();
+ AssignmentPlan assignmentPlan = null;
+ if (this.shouldAssignRegionsWithFavoredNodes) {
+ // Get the assignment domain for this table
+ AssignmentDomain domain = this.getAssignmentDomain(tableName, servers);
+ // Get the assignment plan for the new regions
+ assignmentPlan = regionPlacement.getNewAssignmentPlan(newRegions, domain);
+ }
+ createTable(newRegions, assignmentPlan);
+ }
+
+ private synchronized void createTable(final HRegionInfo[] newRegions, AssignmentPlan assignmentPlan) throws IOException {
String tableName = newRegions[0].getTableDesc().getNameAsString();
// 1. Check to see if table already exists. Get meta region where
// table would sit should it exist. Open scanner on it. If a region
@@ -1499,15 +1570,6 @@ public class HMaster extends HasThread i
if (tableExists(srvr, metaRegionName, tableName)) {
throw new TableExistsException(tableName);
}
- AssignmentPlan assignmentPlan = null;
- if (this.shouldAssignRegionsWithFavoredNodes) {
- // Get the assignment domain for this table
- AssignmentDomain domain = this.getAssignmentDomain(tableName);
- // Get the assignment plan for the new regions
- assignmentPlan =
- regionPlacement.getNewAssignmentPlan(newRegions, domain);
- }
-
if (assignmentPlan == null) {
LOG.info("Generated the assignment plan for new table " + tableName);
} else {
@@ -1545,15 +1607,26 @@ public class HMaster extends HasThread i
// Get all the online region servers
List<HServerAddress> onlineRSList =
this.serverManager.getOnlineRegionServerList();
-
+ return getAssignmentDomain(tableName, onlineRSList);
+ }
+
+ /**
+ * Get the assignment domain for the table. Currently the domain would be
+ * generated by shuffling the passed region servers.
+ *
+ * It would be easy to extend for the multi-tenancy in the future.
+ *
+ * @param tableName
+ * @param servers - list of servers that we want to be included in the plan
+ * @return the assignment domain for the table.
+ */
+ private AssignmentDomain getAssignmentDomain(String tableName, List<HServerAddress> servers) {
// Shuffle the server list based on the tableName
Random random = new Random(tableName.hashCode());
- Collections.shuffle(onlineRSList, random);
-
+ Collections.shuffle(servers, random);
// Add the shuffled server list into the assignment domain
AssignmentDomain domain = new AssignmentDomain(this.conf);
- domain.addServers(onlineRSList);
-
+ domain.addServers(servers);
return domain;
}
Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/RegionPlacement.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/RegionPlacement.java?rev=1567267&r1=1567266&r2=1567267&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/RegionPlacement.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/master/RegionPlacement.java Tue Feb 11 18:28:31 2014
@@ -122,7 +122,7 @@ public class RegionPlacement implements
// Place the secondary and tertiary region server
Map<HRegionInfo, Pair<HServerAddress, HServerAddress>>
secondaryAndTertiaryRSMap =
- this.placeSecondaryAndTertiaryRS(primaryRSMap, domain);
+ this.placeSecondaryAndTertiaryWithRestrictions(primaryRSMap, domain);
// Get the assignment plan by initialization with the primaryRSMap and the
// secondaryAndTertiaryRSMap
@@ -283,6 +283,7 @@ public class RegionPlacement implements
* @return
* @throws IOException
*/
+ @SuppressWarnings("unused")
private Map<HRegionInfo, Pair<HServerAddress,HServerAddress>> placeSecondaryAndTertiaryRS(
Map<HRegionInfo, HServerAddress> primaryRSMap, AssignmentDomain domain)
throws IOException {
Modified: hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java?rev=1567267&r1=1567266&r2=1567267&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java (original)
+++ hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java Tue Feb 11 18:28:31 2014
@@ -30,7 +30,6 @@ import org.apache.commons.logging.LogFac
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.hbase.client.HConnectionManager;
-import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
@@ -489,6 +488,14 @@ public class MiniHBaseCluster {
return index;
}
+ public List<HServerAddress> getRegionServers() throws IOException {
+ List<HServerAddress> servers = new ArrayList<HServerAddress>();
+ for (JVMClusterUtil.RegionServerThread rst: getRegionServerThreads()) {
+ servers.add(rst.getRegionServer().getHServerInfo().getServerAddress());
+ }
+ return servers;
+ }
+
/**
* Add an exception to send when a region server checks back in
* @param serverNumber Which server to send it to
Modified: hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java?rev=1567267&r1=1567266&r2=1567267&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (original)
+++ hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java Tue Feb 11 18:28:31 2014
@@ -60,6 +60,7 @@ public class TestAdmin {
private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
private HBaseAdmin admin;
private static final int NUM_REGION_SERVER = 3;
+
@BeforeClass
public static void setUpBeforeClass() throws Exception {
TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
@@ -653,9 +654,6 @@ public class TestAdmin {
HTableDescriptor htd = this.admin.getTableDescriptor(tableName);
HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster();
- HTable table = new HTable(master.getConfiguration(),
- tableName);
- Map<HRegionInfo, HServerAddress> hriToHsa = table.getRegionsInfo();
// Try adding a column
this.admin.enableTable(tableName);
Added: hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestHackyCreateTable.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestHackyCreateTable.java?rev=1567267&view=auto
==============================================================================
--- hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestHackyCreateTable.java (added)
+++ hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/client/TestHackyCreateTable.java Tue Feb 11 18:28:31 2014
@@ -0,0 +1,143 @@
+/**
+ * Copyright The Apache Software Foundation
+ *
+ * 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.client;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HServerAddress;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Create table only on a set of regionservers instead of whole cluster
+ * JIRA: https://issues.apache.org/jira/browse/HBASE-10425
+ *
+ */
+public class TestHackyCreateTable {
+ final Log LOG = LogFactory.getLog(getClass());
+ private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+ private HBaseAdmin admin;
+ private static final int NUM_REGION_SERVER = 10;
+ /**
+ * Number of regionservers that we will remove in the test from {@link #NUM_REGION_SERVER}
+ */
+ private static final int NUM_REMOVED_RS = 7;
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ TEST_UTIL.getConfiguration().set(HConstants.LOAD_BALANCER_IMPL,
+ "org.apache.hadoop.hbase.master.RegionManager$AssignmentLoadBalancer");
+ TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
+ TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
+ TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
+ TEST_UTIL.startMiniCluster(NUM_REGION_SERVER);
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ TEST_UTIL.shutdownMiniCluster();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ this.admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
+ }
+
+ /**
+ * Create two tables only on specific number of regionservers (subset of all
+ * regionservers). Check after the creation whether the regions are assigned
+ * only to those ones.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testCreateTableOnRegionServers() throws IOException {
+ byte[] tableName = Bytes.toBytes("testCreateTableWithRegionsOnServers");
+ byte[][] splitKeys = {
+ new byte[]{1, 1, 1},
+ new byte[]{2, 2, 2},
+ new byte[]{3, 3, 3},
+ new byte[]{4, 4, 4},
+ new byte[]{5, 5, 5},
+ new byte[]{6, 6, 6},
+ new byte[]{7, 7, 7},
+ new byte[]{8, 8, 8},
+ new byte[]{9, 9, 9},
+ };
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
+ List<HServerAddress> allServers = TEST_UTIL.getHBaseCluster().getRegionServers();
+ System.out.println("initial number of servers: " + allServers.size());
+ // remove some regionservers
+ for (int i = 0; i < NUM_REMOVED_RS; i++) {
+ allServers.remove(0);
+ }
+ // create a table on the remaining regionservers
+ // refresh Admin to pickup new configuration about using favored nodes
+ admin.createTable(desc, splitKeys, allServers);
+ HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
+ Map<HRegionInfo,HServerAddress> regions = ht.getRegionsInfo();
+ int expectedRegions = splitKeys.length + 1;
+ assertEquals("Tried to create " + expectedRegions + " regions " +
+ "but only found " + regions.size(),
+ expectedRegions, regions.size());
+ //verify if we use only a subset of the regionservers
+ Set<HServerAddress> serversForTable = new HashSet<HServerAddress>();
+ serversForTable.addAll(regions.values());
+ assertEquals(NUM_REGION_SERVER - NUM_REMOVED_RS, allServers.size());
+ assertEquals(allServers.size(), serversForTable.size());
+
+ // create one more table only on allServers
+ tableName = Bytes.toBytes("testCreateTableWithRegionsOnServers2");
+ byte[][] splitKeys2 = {
+ new byte[]{1, 1, 1},
+ new byte[]{2, 2, 2}
+ };
+ desc = new HTableDescriptor(tableName);
+ desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
+ admin.createTable(desc, splitKeys2, allServers);
+ ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
+ regions = ht.getRegionsInfo();
+ expectedRegions = splitKeys2.length + 1;
+ assertEquals("Tried to create " + expectedRegions + " regions " +
+ "but only found " + regions.size(),
+ expectedRegions, regions.size());
+ //verify if we use only a subset of the regionservers
+ serversForTable = new HashSet<HServerAddress>();
+ serversForTable.addAll(regions.values());
+ assertEquals(NUM_REGION_SERVER - NUM_REMOVED_RS, allServers.size());
+ assertEquals(allServers.size(), serversForTable.size());
+ }
+}