diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/normalizer/SimpleRegionNormalizer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/normalizer/SimpleRegionNormalizer.java index 8d566f081fb4..d20ba70bfd83 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/normalizer/SimpleRegionNormalizer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/normalizer/SimpleRegionNormalizer.java @@ -63,7 +63,12 @@ public class SimpleRegionNormalizer implements RegionNormalizer { private static final Logger LOG = LoggerFactory.getLogger(SimpleRegionNormalizer.class); - private static final int MIN_REGION_COUNT = 3; + + public static final String HBASE_REGION_NORMALIZER_MIN_REGION_COUNT_KEY = + "hbase.normalizer.min.region.count"; + public static final int HBASE_REGION_NORMALIZER_MIN_REGION_COUNT_DEFAULT = 3; + + protected int minRegionCount; private MasterServices masterServices; private MasterRpcServices masterRpcServices; private static long[] skippedCount = new long[NormalizationPlan.PlanType.values().length]; @@ -75,6 +80,9 @@ public class SimpleRegionNormalizer implements RegionNormalizer { @Override public void setMasterServices(MasterServices masterServices) { this.masterServices = masterServices; + minRegionCount = masterServices.getConfiguration().getInt( + HBASE_REGION_NORMALIZER_MIN_REGION_COUNT_KEY, + HBASE_REGION_NORMALIZER_MIN_REGION_COUNT_DEFAULT); } @Override @@ -148,14 +156,17 @@ public List computePlanForTable(TableName table) throws HBase List tableRegions = masterServices.getAssignmentManager().getRegionStates(). getRegionsOfTable(table); - //TODO: should we make min number of regions a config param? - if (tableRegions == null || tableRegions.size() < MIN_REGION_COUNT) { - int nrRegions = tableRegions == null ? 0 : tableRegions.size(); - LOG.debug("Table " + table + " has " + nrRegions + " regions, required min number" - + " of regions for normalizer to run is " + MIN_REGION_COUNT + ", not running normalizer"); + if (tableRegions == null) { return null; } + if (tableRegions.size() < minRegionCount) { + LOG.debug("Table " + table + " has " + tableRegions.size() + " regions, required min number" + + " of regions for normalizer merging to run is " + minRegionCount + + ", not running normalizer merging"); + mergeEnabled = false; + } + LOG.debug("Computing normalization plan for table: " + table + ", number of regions: " + tableRegions.size()); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/normalizer/TestSimpleRegionNormalizer.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/normalizer/TestSimpleRegionNormalizer.java index 743ec2be4854..fbc78ca040c5 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/normalizer/TestSimpleRegionNormalizer.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/normalizer/TestSimpleRegionNormalizer.java @@ -18,6 +18,7 @@ package org.apache.hadoop.hbase.master.normalizer; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; @@ -28,7 +29,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; + +import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HBaseIOException; import org.apache.hadoop.hbase.RegionMetrics; import org.apache.hadoop.hbase.ServerName; @@ -476,6 +480,46 @@ public void testSplitWithTargetRegionSize() throws Exception { assertEquals(hri2, ((MergeNormalizationPlan) plan).getSecondRegion()); } + @Test + public void testSplitIfTooFewRegions() throws HBaseIOException { + final TableName tableName = TableName.valueOf(name.getMethodName()); + List RegionInfo = new ArrayList<>(); + Map regionSizes = new HashMap<>(); + + RegionInfo hri1 = RegionInfoBuilder.newBuilder(tableName) + .setStartKey(Bytes.toBytes("aaa")) + .setEndKey(Bytes.toBytes("bbb")) + .build(); + RegionInfo.add(hri1); + regionSizes.put(hri1.getRegionName(), 1); + + RegionInfo hri2 = RegionInfoBuilder.newBuilder(tableName) + .setStartKey(Bytes.toBytes("bbb")) + .setEndKey(Bytes.toBytes("ccc")) + .build(); + RegionInfo.add(hri2); + regionSizes.put(hri2.getRegionName(), 1); + // the third region is huge one + RegionInfo hri3 = RegionInfoBuilder.newBuilder(tableName) + .setStartKey(Bytes.toBytes("ccc")) + .setEndKey(Bytes.toBytes("ddd")) + .build(); + RegionInfo.add(hri3); + regionSizes.put(hri3.getRegionName(), 10); + + setupMocksForNormalizer(regionSizes, RegionInfo); + + Configuration configuration = HBaseConfiguration.create(); + configuration.setInt(SimpleRegionNormalizer.HBASE_REGION_NORMALIZER_MIN_REGION_COUNT_KEY, 4); + when(masterServices.getConfiguration()).thenReturn(configuration); + normalizer.setMasterServices(masterServices); + + List plans = normalizer.computePlanForTable(tableName); + assertNotNull(plans); + NormalizationPlan plan = plans.get(0); + assertEquals(hri3, ((SplitNormalizationPlan) plan).getRegionInfo()); + } + @SuppressWarnings("MockitoCast") protected void setupMocksForNormalizer(Map regionSizes, List RegionInfo) {