From 89fe8fbee2dd599dc6b34f54f02e2735d843f328 Mon Sep 17 00:00:00 2001 From: Toshihiro Suzuki Date: Sun, 11 Apr 2021 21:36:04 +0900 Subject: [PATCH 1/7] HBASE-25766 Introduce RegionSplitPointRestriction that restricts the pattern of the split point --- .../assignment/SplitTableRegionProcedure.java | 19 +- ...dKeyPrefixRegionSplitPointRestriction.java | 84 ++++++++ .../DelimitedKeyPrefixRegionSplitPolicy.java | 4 + .../hadoop/hbase/regionserver/HRegion.java | 7 + .../KeyPrefixRegionSplitPointRestriction.java | 76 ++++++++ .../KeyPrefixRegionSplitPolicy.java | 4 + .../NoneRegionSplitPointRestriction.java | 40 ++++ .../RegionSplitPointRestriction.java | 101 ++++++++++ .../TestRegionSplitPointRestriction.java | 184 ++++++++++++++++++ 9 files changed, 514 insertions(+), 5 deletions(-) create mode 100644 hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java create mode 100644 hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java create mode 100644 hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java create mode 100644 hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java create mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java index 3ed60583757d..6b9674ad576b 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java @@ -61,6 +61,7 @@ import org.apache.hadoop.hbase.regionserver.HRegionFileSystem; import org.apache.hadoop.hbase.regionserver.HStore; import org.apache.hadoop.hbase.regionserver.HStoreFile; +import org.apache.hadoop.hbase.regionserver.RegionSplitPointRestriction; import org.apache.hadoop.hbase.regionserver.RegionSplitPolicy; import org.apache.hadoop.hbase.regionserver.StoreFileInfo; import org.apache.hadoop.hbase.util.Bytes; @@ -110,6 +111,15 @@ public SplitTableRegionProcedure(final MasterProcedureEnv env, // we fail-fast on construction. There it skips the split with just a warning. checkOnline(env, regionToSplit); this.bestSplitRow = splitRow; + TableDescriptor tableDescriptor = env.getMasterServices().getTableDescriptors() + .get(getTableName()); + Configuration conf = env.getMasterConfiguration(); + if (hasBestSplitRow()) { + // Apply the split point restriction for the table to the user-specified split point + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + bestSplitRow = splitPointRestriction.getRestrictedSplitPoint(bestSplitRow); + } checkSplittable(env, regionToSplit); final TableName table = regionToSplit.getTable(); final long rid = getDaughterRegionIdTimestamp(regionToSplit); @@ -125,15 +135,14 @@ public SplitTableRegionProcedure(final MasterProcedureEnv env, .setSplit(false) .setRegionId(rid) .build(); - TableDescriptor htd = env.getMasterServices().getTableDescriptors().get(getTableName()); - if(htd.getRegionSplitPolicyClassName() != null) { + if(tableDescriptor.getRegionSplitPolicyClassName() != null) { // Since we don't have region reference here, creating the split policy instance without it. // This can be used to invoke methods which don't require Region reference. This instantiation // of a class on Master-side though it only makes sense on the RegionServer-side is // for Phoenix Local Indexing. Refer HBASE-12583 for more information. Class clazz = - RegionSplitPolicy.getSplitPolicyClass(htd, env.getMasterConfiguration()); - this.splitPolicy = ReflectionUtils.newInstance(clazz, env.getMasterConfiguration()); + RegionSplitPolicy.getSplitPolicyClass(tableDescriptor, conf); + this.splitPolicy = ReflectionUtils.newInstance(clazz, conf); } } @@ -219,7 +228,7 @@ private void checkSplittable(final MasterProcedureEnv env, throw e; } - if (bestSplitRow == null || bestSplitRow.length == 0) { + if (!hasBestSplitRow()) { throw new DoNotRetryIOException("Region not splittable because bestSplitPoint = null, " + "maybe table is too small for auto split. For force split, try specifying split row"); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java new file mode 100644 index 000000000000..932d12c923d2 --- /dev/null +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java @@ -0,0 +1,84 @@ +/* + * 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.regionserver; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.client.TableDescriptor; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.yetus.audience.InterfaceAudience; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.util.Arrays; + +/** + * A RegionSplitPointRestriction implementation that groups rows by a prefix of the row-key with a + * delimiter. Only the first delimiter for the row key will define the prefix of the row key that + * is used for grouping. + * + * This ensures that a region is not split "inside" a prefix of a row key. + * I.e. rows can be co-located in a region by their prefix. + * + * As an example, if you have row keys delimited with _, like + * userid_eventtype_eventid, and use prefix delimiter _, this split policy ensures + * that all rows starting with the same userid, belongs to the same region. + */ +@InterfaceAudience.Private +public class DelimitedKeyPrefixRegionSplitPointRestriction extends RegionSplitPointRestriction { + private static final Logger LOGGER = + LoggerFactory.getLogger(DelimitedKeyPrefixRegionSplitPointRestriction.class); + + public static final String DELIMITER_KEY = + "hbase.regionserver.region.split_point_restriction.delimiter"; + + private byte[] delimiter = null; + + @Override + public void initialize(TableDescriptor tableDescriptor, Configuration conf) throws IOException { + String delimiterString = tableDescriptor.getValue(DELIMITER_KEY); + if (delimiterString == null || delimiterString.length() == 0) { + delimiterString = conf.get(DELIMITER_KEY); + if (delimiterString == null || delimiterString.length() == 0) { + LOGGER.error("{} not specified for table {}. " + + "Using the default RegionSplitPointRestriction", DELIMITER_KEY, + tableDescriptor.getTableName()); + return; + } + } + delimiter = Bytes.toBytes(delimiterString); + } + + @Override + public byte[] getRestrictedSplitPoint(byte[] splitPoint) { + if (delimiter != null) { + // find the first occurrence of delimiter in split point + int index = org.apache.hbase.thirdparty.com.google.common.primitives.Bytes.indexOf( + splitPoint, delimiter); + if (index < 0) { + LOGGER.warn("Delimiter {} not found for split key {}", Bytes.toString(delimiter), + Bytes.toStringBinary(splitPoint)); + return splitPoint; + } + + // group split keys by a prefix + return Arrays.copyOf(splitPoint, Math.min(index, splitPoint.length)); + } else { + return splitPoint; + } + } +} diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPolicy.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPolicy.java index d6a3b7e6638c..895e9ad71822 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPolicy.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPolicy.java @@ -37,7 +37,11 @@ * userid_eventtype_eventid, and use prefix delimiter _, this split policy * ensures that all rows starting with the same userid, belongs to the same region. * @see KeyPrefixRegionSplitPolicy + * + * @deprecated since 3.0.0 and will be removed in 4.0.0. Use {@link RegionSplitPointRestriction}, + * instead. */ +@Deprecated @InterfaceAudience.Private public class DelimitedKeyPrefixRegionSplitPolicy extends IncreasingToUpperBoundRegionSplitPolicy { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 9da7f7c8d839..368cfcf15788 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -695,6 +695,7 @@ void sawNoSuchFamily() { private TableDescriptor htableDescriptor = null; private RegionSplitPolicy splitPolicy; + private RegionSplitPointRestriction splitPointRestriction; private FlushPolicy flushPolicy; private final MetricsRegion metricsRegion; @@ -1037,6 +1038,9 @@ private long initializeRegionInternals(final CancelableProgressable reporter, // Initialize split policy this.splitPolicy = RegionSplitPolicy.create(this, conf); + // Initialize split restriction + splitPointRestriction = RegionSplitPointRestriction.create(getTableDescriptor(), conf); + // Initialize flush policy this.flushPolicy = FlushPolicyFactory.create(this, conf); @@ -7870,6 +7874,9 @@ public Optional checkSplit(boolean force) { } byte[] ret = splitPolicy.getSplitPoint(); + if (ret != null && ret.length > 0) { + ret = splitPointRestriction.getRestrictedSplitPoint(ret); + } if (ret != null) { try { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java new file mode 100644 index 000000000000..fe1ed2b09b4e --- /dev/null +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java @@ -0,0 +1,76 @@ +/* + * 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.regionserver; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.client.TableDescriptor; +import org.apache.yetus.audience.InterfaceAudience; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.util.Arrays; + +/** + * A RegionSplitPointRestriction implementation that groups rows by a prefix of the row-key. + * + * This ensures that a region is not split "inside" a prefix of a row key. + * I.e. rows can be co-located in a region by their prefix. + */ +@InterfaceAudience.Private +public class KeyPrefixRegionSplitPointRestriction extends RegionSplitPointRestriction { + private static final Logger LOGGER = + LoggerFactory.getLogger(KeyPrefixRegionSplitPointRestriction.class); + + public static final String PREFIX_LENGTH_KEY = + "hbase.regionserver.region.split_point_restriction.prefix_length"; + + private int prefixLength; + + @Override + public void initialize(TableDescriptor tableDescriptor, Configuration conf) throws IOException { + String prefixLengthString = tableDescriptor.getValue(PREFIX_LENGTH_KEY); + if (prefixLengthString == null) { + prefixLengthString = conf.get(PREFIX_LENGTH_KEY); + if (prefixLengthString == null) { + LOGGER.error("{} not specified for table {}. " + + "Using the default RegionSplitPointRestriction", PREFIX_LENGTH_KEY, + tableDescriptor.getTableName()); + return; + } + } + try { + prefixLength = Integer.parseInt(prefixLengthString); + } catch (NumberFormatException ignored) { + } + if (prefixLength <= 0) { + LOGGER.error("Invalid value for {} for table {}:{}. " + + "Using the default RegionSplitPointRestriction", PREFIX_LENGTH_KEY, + tableDescriptor.getTableName(), prefixLengthString); + } + } + + @Override + public byte[] getRestrictedSplitPoint(byte[] splitPoint) { + if (prefixLength > 0) { + // group split keys by a prefix + return Arrays.copyOf(splitPoint, Math.min(prefixLength, splitPoint.length)); + } else { + return splitPoint; + } + } +} diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java index 29c7d11ac1d4..8c99585cac52 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java @@ -29,7 +29,11 @@ * * This ensures that a region is not split "inside" a prefix of a row key. * I.e. rows can be co-located in a region by their prefix. + * + * @deprecated since 3.0.0 and will be removed in 4.0.0. Use {@link RegionSplitPointRestriction}, + * instead. */ +@Deprecated @InterfaceAudience.Private public class KeyPrefixRegionSplitPolicy extends IncreasingToUpperBoundRegionSplitPolicy { private static final Logger LOG = LoggerFactory diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java new file mode 100644 index 000000000000..31048e65defa --- /dev/null +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java @@ -0,0 +1,40 @@ +/* + * 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.regionserver; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.client.TableDescriptor; +import org.apache.yetus.audience.InterfaceAudience; +import java.io.IOException; + +/** + * A RegionSplitPointRestriction implementation that does nothing. + */ +@InterfaceAudience.Private +public class NoneRegionSplitPointRestriction extends RegionSplitPointRestriction { + + @Override + public void initialize(TableDescriptor tableDescriptor, Configuration conf) throws IOException { + } + + @Override + public byte[] getRestrictedSplitPoint(byte[] splitPoint) { + // Do nothing + return splitPoint; + } +} diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java new file mode 100644 index 000000000000..ac0aeaa35dbc --- /dev/null +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java @@ -0,0 +1,101 @@ +/* + * 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.regionserver; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.client.TableDescriptor; +import org.apache.yetus.audience.InterfaceAudience; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * A split point restriction that restricts the pattern of the split point. + * + * There are three implementations as follows: + * @see NoneRegionSplitPointRestriction + * @see KeyPrefixRegionSplitPointRestriction + * @see DelimitedKeyPrefixRegionSplitPointRestriction + */ +@InterfaceAudience.Private +public abstract class RegionSplitPointRestriction { + private static final Logger LOGGER = LoggerFactory.getLogger(RegionSplitPointRestriction.class); + + public static final String RESTRICTION_TYPE_KEY = + "hbase.regionserver.region.split_point_restriction.type"; + + public static final String RESTRICTION_TYPE_NONE = "None"; + public static final String RESTRICTION_TYPE_KEY_PREFIX = "KeyPrefix"; + public static final String RESTRICTION_TYPE_DELIMITED_KEY_PREFIX = "DelimitedKeyPrefix"; + + /** + * Create the RegionSplitPointRestriction configured for the given table. + * + * @param tableDescriptor the table descriptor + * @param conf the configuration + * @return a RegionSplitPointRestriction instance + * @throws IOException if an error occurs + */ + public static RegionSplitPointRestriction create(TableDescriptor tableDescriptor, + Configuration conf) throws IOException { + String type = tableDescriptor.getValue(RESTRICTION_TYPE_KEY); + if (type == null) { + type = conf.get(RESTRICTION_TYPE_KEY, RESTRICTION_TYPE_NONE); + } + + RegionSplitPointRestriction ret; + switch (type) { + case RESTRICTION_TYPE_NONE: + ret = new NoneRegionSplitPointRestriction(); + break; + case RESTRICTION_TYPE_KEY_PREFIX: + ret = new KeyPrefixRegionSplitPointRestriction(); + break; + case RESTRICTION_TYPE_DELIMITED_KEY_PREFIX: + ret = new DelimitedKeyPrefixRegionSplitPointRestriction(); + break; + default: + LOGGER.warn("Invalid RegionSplitPointRestriction type specified: {}. " + + "Using the default RegionSplitPointRestriction", type); + ret = new NoneRegionSplitPointRestriction(); + break; + } + ret.initialize(tableDescriptor, conf); + return ret; + } + + /** + * Initialize the RegionSplitPointRestriction instance + * + * @param tableDescriptor the table descriptor + * @param conf the configuration + * @throws IOException if an error occurs + */ + public abstract void initialize(TableDescriptor tableDescriptor, Configuration conf) + throws IOException; + + /** + * Returns a restricted split point. + * + * @param splitPoint the split point determined by {@link RegionSplitPolicy} or specified by a + * user manually + * @return the restricted split point + */ + public abstract byte[] getRestrictedSplitPoint(byte[] splitPoint); +} diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java new file mode 100644 index 000000000000..408ac1f213ad --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java @@ -0,0 +1,184 @@ +/* + * 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.regionserver; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.client.TableDescriptor; +import org.apache.hadoop.hbase.testclassification.RegionServerTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import java.io.IOException; + +@Category({ RegionServerTests.class, SmallTests.class }) +public class TestRegionSplitPointRestriction { + + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestRegionSplitPointRestriction.class); + + Configuration conf; + @Mock TableDescriptor tableDescriptor; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + conf = new Configuration(); + } + + @Test + public void testWhenTableDescriptorReturnsNoneType() throws IOException { + when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_NONE); + + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + assertTrue(splitPointRestriction instanceof NoneRegionSplitPointRestriction); + } + + @Test + public void testWhenTableDescriptorReturnsKeyPrefixType() throws IOException { + when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY_PREFIX); + + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + assertTrue(splitPointRestriction instanceof KeyPrefixRegionSplitPointRestriction); + } + + @Test + public void testWhenTableDescriptorReturnsDelimitedKeyPrefixType() throws IOException { + when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); + + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + assertTrue(splitPointRestriction instanceof DelimitedKeyPrefixRegionSplitPointRestriction); + } + + @Test + public void testWhenConfigurationReturnsNoneType() throws IOException { + conf.set(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY, + RegionSplitPointRestriction.RESTRICTION_TYPE_NONE); + + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + assertTrue(splitPointRestriction instanceof NoneRegionSplitPointRestriction); + } + + @Test + public void testWhenConfigurationReturnsKeyPrefixType() throws IOException { + conf.set(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY, + RegionSplitPointRestriction.RESTRICTION_TYPE_KEY_PREFIX); + + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + assertTrue(splitPointRestriction instanceof KeyPrefixRegionSplitPointRestriction); + } + + @Test + public void testWhenConfigurationReturnsDelimitedKeyPrefixType() throws IOException { + conf.set(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY, + RegionSplitPointRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); + + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + assertTrue(splitPointRestriction instanceof DelimitedKeyPrefixRegionSplitPointRestriction); + } + + @Test + public void testWhenTableDescriptorAndConfigurationReturnNull() throws IOException { + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + assertTrue(splitPointRestriction instanceof NoneRegionSplitPointRestriction); + } + + @Test + public void testWhenTableDescriptorReturnsInvalidType() throws IOException { + when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn("Invalid"); + + RegionSplitPointRestriction splitPointRestriction = + RegionSplitPointRestriction.create(tableDescriptor, conf); + assertTrue(splitPointRestriction instanceof NoneRegionSplitPointRestriction); + } + + @Test + public void testNoneRegionSplitPointRestriction() throws IOException { + when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_NONE); + + NoneRegionSplitPointRestriction noneRegionSplitPointRestriction = + (NoneRegionSplitPointRestriction) RegionSplitPointRestriction.create(tableDescriptor, conf); + + byte[] restrictedSplitPoint = + noneRegionSplitPointRestriction.getRestrictedSplitPoint(Bytes.toBytes("abcd")); + assertEquals("abcd", Bytes.toString(restrictedSplitPoint)); + } + + @Test + public void testKeyPrefixRegionSplitPointRestriction() throws IOException { + when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY_PREFIX); + when(tableDescriptor.getValue(KeyPrefixRegionSplitPointRestriction.PREFIX_LENGTH_KEY)) + .thenReturn("2"); + + KeyPrefixRegionSplitPointRestriction keyPrefixRegionSplitPointRestriction = + (KeyPrefixRegionSplitPointRestriction) RegionSplitPointRestriction.create( + tableDescriptor, conf); + + byte[] restrictedSplitPoint = + keyPrefixRegionSplitPointRestriction.getRestrictedSplitPoint(Bytes.toBytes("abcd")); + assertEquals("ab", Bytes.toString(restrictedSplitPoint)); + + restrictedSplitPoint = + keyPrefixRegionSplitPointRestriction.getRestrictedSplitPoint(Bytes.toBytes("a")); + assertEquals("a", Bytes.toString(restrictedSplitPoint)); + } + + @Test + public void testDelimitedKeyPrefixRegionSplitPointRestriction() throws IOException { + when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); + when(tableDescriptor.getValue(DelimitedKeyPrefixRegionSplitPointRestriction.DELIMITER_KEY)) + .thenReturn(","); + + DelimitedKeyPrefixRegionSplitPointRestriction delimitedKeyPrefixRegionSplitPointRestriction = + (DelimitedKeyPrefixRegionSplitPointRestriction) RegionSplitPointRestriction.create( + tableDescriptor, conf); + + byte[] restrictedSplitPoint = delimitedKeyPrefixRegionSplitPointRestriction + .getRestrictedSplitPoint(Bytes.toBytes("ab,cd")); + assertEquals("ab", Bytes.toString(restrictedSplitPoint)); + + restrictedSplitPoint = delimitedKeyPrefixRegionSplitPointRestriction + .getRestrictedSplitPoint(Bytes.toBytes("ijk")); + assertEquals("ijk", Bytes.toString(restrictedSplitPoint)); + } +} From c5b26ed7896669a31141d368c3ae3489e19ea35f Mon Sep 17 00:00:00 2001 From: Toshihiro Suzuki Date: Mon, 12 Apr 2021 11:36:06 +0900 Subject: [PATCH 2/7] Fix checkstyle errors --- .../DelimitedKeyPrefixRegionSplitPointRestriction.java | 4 ++-- .../regionserver/KeyPrefixRegionSplitPointRestriction.java | 4 ++-- .../hbase/regionserver/NoneRegionSplitPointRestriction.java | 2 +- .../hbase/regionserver/RegionSplitPointRestriction.java | 3 +-- .../hbase/regionserver/TestRegionSplitPointRestriction.java | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java index 932d12c923d2..767bae48e64b 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java @@ -17,14 +17,14 @@ */ package org.apache.hadoop.hbase.regionserver; +import java.io.IOException; +import java.util.Arrays; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.hadoop.hbase.util.Bytes; import org.apache.yetus.audience.InterfaceAudience; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.Arrays; /** * A RegionSplitPointRestriction implementation that groups rows by a prefix of the row-key with a diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java index fe1ed2b09b4e..faca9b1d0c29 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java @@ -17,13 +17,13 @@ */ package org.apache.hadoop.hbase.regionserver; +import java.io.IOException; +import java.util.Arrays; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.yetus.audience.InterfaceAudience; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.Arrays; /** * A RegionSplitPointRestriction implementation that groups rows by a prefix of the row-key. diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java index 31048e65defa..50989d90c056 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java @@ -17,10 +17,10 @@ */ package org.apache.hadoop.hbase.regionserver; +import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.yetus.audience.InterfaceAudience; -import java.io.IOException; /** * A RegionSplitPointRestriction implementation that does nothing. diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java index ac0aeaa35dbc..f3bd3a133f2f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java @@ -17,14 +17,13 @@ */ package org.apache.hadoop.hbase.regionserver; +import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.yetus.audience.InterfaceAudience; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; - /** * A split point restriction that restricts the pattern of the split point. * diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java index 408ac1f213ad..cee453378910 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.client.TableDescriptor; @@ -33,7 +34,6 @@ import org.junit.experimental.categories.Category; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.io.IOException; @Category({ RegionServerTests.class, SmallTests.class }) public class TestRegionSplitPointRestriction { From c7f0cd6354212d34e79fe5417cdea8bc012d4870 Mon Sep 17 00:00:00 2001 From: Toshihiro Suzuki Date: Fri, 16 Apr 2021 22:36:08 +0900 Subject: [PATCH 3/7] Some small modifications based on the reviews --- ...imitedKeyPrefixRegionSplitPointRestriction.java | 6 +++--- .../KeyPrefixRegionSplitPointRestriction.java | 6 +++--- ...ion.java => NoRegionSplitPointRestriction.java} | 2 +- .../regionserver/RegionSplitPointRestriction.java | 10 +++++----- .../TestRegionSplitPointRestriction.java | 14 +++++++------- 5 files changed, 19 insertions(+), 19 deletions(-) rename hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/{NoneRegionSplitPointRestriction.java => NoRegionSplitPointRestriction.java} (94%) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java index 767bae48e64b..033a018f6b3a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java @@ -40,7 +40,7 @@ */ @InterfaceAudience.Private public class DelimitedKeyPrefixRegionSplitPointRestriction extends RegionSplitPointRestriction { - private static final Logger LOGGER = + private static final Logger LOG = LoggerFactory.getLogger(DelimitedKeyPrefixRegionSplitPointRestriction.class); public static final String DELIMITER_KEY = @@ -54,7 +54,7 @@ public void initialize(TableDescriptor tableDescriptor, Configuration conf) thro if (delimiterString == null || delimiterString.length() == 0) { delimiterString = conf.get(DELIMITER_KEY); if (delimiterString == null || delimiterString.length() == 0) { - LOGGER.error("{} not specified for table {}. " + LOG.error("{} not specified for table {}. " + "Using the default RegionSplitPointRestriction", DELIMITER_KEY, tableDescriptor.getTableName()); return; @@ -70,7 +70,7 @@ public byte[] getRestrictedSplitPoint(byte[] splitPoint) { int index = org.apache.hbase.thirdparty.com.google.common.primitives.Bytes.indexOf( splitPoint, delimiter); if (index < 0) { - LOGGER.warn("Delimiter {} not found for split key {}", Bytes.toString(delimiter), + LOG.warn("Delimiter {} not found for split key {}", Bytes.toString(delimiter), Bytes.toStringBinary(splitPoint)); return splitPoint; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java index faca9b1d0c29..f0224db87585 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java @@ -33,7 +33,7 @@ */ @InterfaceAudience.Private public class KeyPrefixRegionSplitPointRestriction extends RegionSplitPointRestriction { - private static final Logger LOGGER = + private static final Logger LOG = LoggerFactory.getLogger(KeyPrefixRegionSplitPointRestriction.class); public static final String PREFIX_LENGTH_KEY = @@ -47,7 +47,7 @@ public void initialize(TableDescriptor tableDescriptor, Configuration conf) thro if (prefixLengthString == null) { prefixLengthString = conf.get(PREFIX_LENGTH_KEY); if (prefixLengthString == null) { - LOGGER.error("{} not specified for table {}. " + LOG.error("{} not specified for table {}. " + "Using the default RegionSplitPointRestriction", PREFIX_LENGTH_KEY, tableDescriptor.getTableName()); return; @@ -58,7 +58,7 @@ public void initialize(TableDescriptor tableDescriptor, Configuration conf) thro } catch (NumberFormatException ignored) { } if (prefixLength <= 0) { - LOGGER.error("Invalid value for {} for table {}:{}. " + LOG.error("Invalid value for {} for table {}:{}. " + "Using the default RegionSplitPointRestriction", PREFIX_LENGTH_KEY, tableDescriptor.getTableName(), prefixLengthString); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitPointRestriction.java similarity index 94% rename from hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java rename to hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitPointRestriction.java index 50989d90c056..7ccdc4d9426d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoneRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitPointRestriction.java @@ -26,7 +26,7 @@ * A RegionSplitPointRestriction implementation that does nothing. */ @InterfaceAudience.Private -public class NoneRegionSplitPointRestriction extends RegionSplitPointRestriction { +public class NoRegionSplitPointRestriction extends RegionSplitPointRestriction { @Override public void initialize(TableDescriptor tableDescriptor, Configuration conf) throws IOException { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java index f3bd3a133f2f..5072554ceb38 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java @@ -28,13 +28,13 @@ * A split point restriction that restricts the pattern of the split point. * * There are three implementations as follows: - * @see NoneRegionSplitPointRestriction + * @see NoRegionSplitPointRestriction * @see KeyPrefixRegionSplitPointRestriction * @see DelimitedKeyPrefixRegionSplitPointRestriction */ @InterfaceAudience.Private public abstract class RegionSplitPointRestriction { - private static final Logger LOGGER = LoggerFactory.getLogger(RegionSplitPointRestriction.class); + private static final Logger LOG = LoggerFactory.getLogger(RegionSplitPointRestriction.class); public static final String RESTRICTION_TYPE_KEY = "hbase.regionserver.region.split_point_restriction.type"; @@ -61,7 +61,7 @@ public static RegionSplitPointRestriction create(TableDescriptor tableDescriptor RegionSplitPointRestriction ret; switch (type) { case RESTRICTION_TYPE_NONE: - ret = new NoneRegionSplitPointRestriction(); + ret = new NoRegionSplitPointRestriction(); break; case RESTRICTION_TYPE_KEY_PREFIX: ret = new KeyPrefixRegionSplitPointRestriction(); @@ -70,9 +70,9 @@ public static RegionSplitPointRestriction create(TableDescriptor tableDescriptor ret = new DelimitedKeyPrefixRegionSplitPointRestriction(); break; default: - LOGGER.warn("Invalid RegionSplitPointRestriction type specified: {}. " + LOG.warn("Invalid RegionSplitPointRestriction type specified: {}. " + "Using the default RegionSplitPointRestriction", type); - ret = new NoneRegionSplitPointRestriction(); + ret = new NoRegionSplitPointRestriction(); break; } ret.initialize(tableDescriptor, conf); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java index cee453378910..640fcb7d342c 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java @@ -59,7 +59,7 @@ public void testWhenTableDescriptorReturnsNoneType() throws IOException { RegionSplitPointRestriction splitPointRestriction = RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof NoneRegionSplitPointRestriction); + assertTrue(splitPointRestriction instanceof NoRegionSplitPointRestriction); } @Test @@ -89,7 +89,7 @@ public void testWhenConfigurationReturnsNoneType() throws IOException { RegionSplitPointRestriction splitPointRestriction = RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof NoneRegionSplitPointRestriction); + assertTrue(splitPointRestriction instanceof NoRegionSplitPointRestriction); } @Test @@ -116,7 +116,7 @@ public void testWhenConfigurationReturnsDelimitedKeyPrefixType() throws IOExcept public void testWhenTableDescriptorAndConfigurationReturnNull() throws IOException { RegionSplitPointRestriction splitPointRestriction = RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof NoneRegionSplitPointRestriction); + assertTrue(splitPointRestriction instanceof NoRegionSplitPointRestriction); } @Test @@ -126,7 +126,7 @@ public void testWhenTableDescriptorReturnsInvalidType() throws IOException { RegionSplitPointRestriction splitPointRestriction = RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof NoneRegionSplitPointRestriction); + assertTrue(splitPointRestriction instanceof NoRegionSplitPointRestriction); } @Test @@ -134,11 +134,11 @@ public void testNoneRegionSplitPointRestriction() throws IOException { when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_NONE); - NoneRegionSplitPointRestriction noneRegionSplitPointRestriction = - (NoneRegionSplitPointRestriction) RegionSplitPointRestriction.create(tableDescriptor, conf); + NoRegionSplitPointRestriction noRegionSplitPointRestriction = + (NoRegionSplitPointRestriction) RegionSplitPointRestriction.create(tableDescriptor, conf); byte[] restrictedSplitPoint = - noneRegionSplitPointRestriction.getRestrictedSplitPoint(Bytes.toBytes("abcd")); + noRegionSplitPointRestriction.getRestrictedSplitPoint(Bytes.toBytes("abcd")); assertEquals("abcd", Bytes.toString(restrictedSplitPoint)); } From 6de690887adee7ae8b893eb9a773d4709e426479 Mon Sep 17 00:00:00 2001 From: Toshihiro Suzuki Date: Tue, 20 Apr 2021 17:19:21 +0900 Subject: [PATCH 4/7] Rename RegionSplitPointRestriction to RegionSplitRestriction --- .../assignment/SplitTableRegionProcedure.java | 10 +- .../DelimitedKeyPrefixRegionSplitPolicy.java | 2 +- ...mitedKeyPrefixRegionSplitRestriction.java} | 10 +- .../hadoop/hbase/regionserver/HRegion.java | 6 +- .../KeyPrefixRegionSplitPolicy.java | 2 +- ...a => KeyPrefixRegionSplitRestriction.java} | 12 +- ...ion.java => NoRegionSplitRestriction.java} | 4 +- ...ction.java => RegionSplitRestriction.java} | 36 ++-- .../TestRegionSplitPointRestriction.java | 184 ------------------ .../TestRegionSplitRestriction.java | 184 ++++++++++++++++++ 10 files changed, 225 insertions(+), 225 deletions(-) rename hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/{DelimitedKeyPrefixRegionSplitPointRestriction.java => DelimitedKeyPrefixRegionSplitRestriction.java} (87%) rename hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/{KeyPrefixRegionSplitPointRestriction.java => KeyPrefixRegionSplitRestriction.java} (83%) rename hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/{NoRegionSplitPointRestriction.java => NoRegionSplitRestriction.java} (89%) rename hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/{RegionSplitPointRestriction.java => RegionSplitRestriction.java} (72%) delete mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java create mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitRestriction.java diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java index 6b9674ad576b..b0fa05c9a42d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java @@ -61,7 +61,7 @@ import org.apache.hadoop.hbase.regionserver.HRegionFileSystem; import org.apache.hadoop.hbase.regionserver.HStore; import org.apache.hadoop.hbase.regionserver.HStoreFile; -import org.apache.hadoop.hbase.regionserver.RegionSplitPointRestriction; +import org.apache.hadoop.hbase.regionserver.RegionSplitRestriction; import org.apache.hadoop.hbase.regionserver.RegionSplitPolicy; import org.apache.hadoop.hbase.regionserver.StoreFileInfo; import org.apache.hadoop.hbase.util.Bytes; @@ -115,10 +115,10 @@ public SplitTableRegionProcedure(final MasterProcedureEnv env, .get(getTableName()); Configuration conf = env.getMasterConfiguration(); if (hasBestSplitRow()) { - // Apply the split point restriction for the table to the user-specified split point - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - bestSplitRow = splitPointRestriction.getRestrictedSplitPoint(bestSplitRow); + // Apply the split restriction for the table to the user-specified split point + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + bestSplitRow = splitRestriction.getRestrictedSplitPoint(bestSplitRow); } checkSplittable(env, regionToSplit); final TableName table = regionToSplit.getTable(); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPolicy.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPolicy.java index 895e9ad71822..241c062c6497 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPolicy.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPolicy.java @@ -38,7 +38,7 @@ * ensures that all rows starting with the same userid, belongs to the same region. * @see KeyPrefixRegionSplitPolicy * - * @deprecated since 3.0.0 and will be removed in 4.0.0. Use {@link RegionSplitPointRestriction}, + * @deprecated since 3.0.0 and will be removed in 4.0.0. Use {@link RegionSplitRestriction}, * instead. */ @Deprecated diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java similarity index 87% rename from hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java rename to hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java index 033a018f6b3a..ebdd0c00299f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java @@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory; /** - * A RegionSplitPointRestriction implementation that groups rows by a prefix of the row-key with a + * A RegionSplitRestriction implementation that groups rows by a prefix of the row-key with a * delimiter. Only the first delimiter for the row key will define the prefix of the row key that * is used for grouping. * @@ -39,12 +39,12 @@ * that all rows starting with the same userid, belongs to the same region. */ @InterfaceAudience.Private -public class DelimitedKeyPrefixRegionSplitPointRestriction extends RegionSplitPointRestriction { +public class DelimitedKeyPrefixRegionSplitRestriction extends RegionSplitRestriction { private static final Logger LOG = - LoggerFactory.getLogger(DelimitedKeyPrefixRegionSplitPointRestriction.class); + LoggerFactory.getLogger(DelimitedKeyPrefixRegionSplitRestriction.class); public static final String DELIMITER_KEY = - "hbase.regionserver.region.split_point_restriction.delimiter"; + "hbase.regionserver.region.split_restriction.delimiter"; private byte[] delimiter = null; @@ -55,7 +55,7 @@ public void initialize(TableDescriptor tableDescriptor, Configuration conf) thro delimiterString = conf.get(DELIMITER_KEY); if (delimiterString == null || delimiterString.length() == 0) { LOG.error("{} not specified for table {}. " - + "Using the default RegionSplitPointRestriction", DELIMITER_KEY, + + "Using the default RegionSplitRestriction", DELIMITER_KEY, tableDescriptor.getTableName()); return; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 368cfcf15788..05fbb1ce2192 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -695,7 +695,7 @@ void sawNoSuchFamily() { private TableDescriptor htableDescriptor = null; private RegionSplitPolicy splitPolicy; - private RegionSplitPointRestriction splitPointRestriction; + private RegionSplitRestriction splitRestriction; private FlushPolicy flushPolicy; private final MetricsRegion metricsRegion; @@ -1039,7 +1039,7 @@ private long initializeRegionInternals(final CancelableProgressable reporter, this.splitPolicy = RegionSplitPolicy.create(this, conf); // Initialize split restriction - splitPointRestriction = RegionSplitPointRestriction.create(getTableDescriptor(), conf); + splitRestriction = RegionSplitRestriction.create(getTableDescriptor(), conf); // Initialize flush policy this.flushPolicy = FlushPolicyFactory.create(this, conf); @@ -7875,7 +7875,7 @@ public Optional checkSplit(boolean force) { byte[] ret = splitPolicy.getSplitPoint(); if (ret != null && ret.length > 0) { - ret = splitPointRestriction.getRestrictedSplitPoint(ret); + ret = splitRestriction.getRestrictedSplitPoint(ret); } if (ret != null) { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java index 8c99585cac52..b96361d8feb8 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java @@ -30,7 +30,7 @@ * This ensures that a region is not split "inside" a prefix of a row key. * I.e. rows can be co-located in a region by their prefix. * - * @deprecated since 3.0.0 and will be removed in 4.0.0. Use {@link RegionSplitPointRestriction}, + * @deprecated since 3.0.0 and will be removed in 4.0.0. Use {@link RegionSplitRestriction}, * instead. */ @Deprecated diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java similarity index 83% rename from hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java rename to hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java index f0224db87585..627722bee0d8 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java @@ -26,18 +26,18 @@ import org.slf4j.LoggerFactory; /** - * A RegionSplitPointRestriction implementation that groups rows by a prefix of the row-key. + * A RegionSplitRestriction implementation that groups rows by a prefix of the row-key. * * This ensures that a region is not split "inside" a prefix of a row key. * I.e. rows can be co-located in a region by their prefix. */ @InterfaceAudience.Private -public class KeyPrefixRegionSplitPointRestriction extends RegionSplitPointRestriction { +public class KeyPrefixRegionSplitRestriction extends RegionSplitRestriction { private static final Logger LOG = - LoggerFactory.getLogger(KeyPrefixRegionSplitPointRestriction.class); + LoggerFactory.getLogger(KeyPrefixRegionSplitRestriction.class); public static final String PREFIX_LENGTH_KEY = - "hbase.regionserver.region.split_point_restriction.prefix_length"; + "hbase.regionserver.region.split_restriction.prefix_length"; private int prefixLength; @@ -48,7 +48,7 @@ public void initialize(TableDescriptor tableDescriptor, Configuration conf) thro prefixLengthString = conf.get(PREFIX_LENGTH_KEY); if (prefixLengthString == null) { LOG.error("{} not specified for table {}. " - + "Using the default RegionSplitPointRestriction", PREFIX_LENGTH_KEY, + + "Using the default RegionSplitRestriction", PREFIX_LENGTH_KEY, tableDescriptor.getTableName()); return; } @@ -59,7 +59,7 @@ public void initialize(TableDescriptor tableDescriptor, Configuration conf) thro } if (prefixLength <= 0) { LOG.error("Invalid value for {} for table {}:{}. " - + "Using the default RegionSplitPointRestriction", PREFIX_LENGTH_KEY, + + "Using the default RegionSplitRestriction", PREFIX_LENGTH_KEY, tableDescriptor.getTableName(), prefixLengthString); } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitRestriction.java similarity index 89% rename from hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitPointRestriction.java rename to hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitRestriction.java index 7ccdc4d9426d..6e5969ef7e3a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitRestriction.java @@ -23,10 +23,10 @@ import org.apache.yetus.audience.InterfaceAudience; /** - * A RegionSplitPointRestriction implementation that does nothing. + * A RegionSplitRestriction implementation that does nothing. */ @InterfaceAudience.Private -public class NoRegionSplitPointRestriction extends RegionSplitPointRestriction { +public class NoRegionSplitRestriction extends RegionSplitRestriction { @Override public void initialize(TableDescriptor tableDescriptor, Configuration conf) throws IOException { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java similarity index 72% rename from hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java rename to hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java index 5072554ceb38..64bf94f55d10 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitPointRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java @@ -25,54 +25,54 @@ import org.slf4j.LoggerFactory; /** - * A split point restriction that restricts the pattern of the split point. + * A split restriction that restricts the pattern of the split point. * * There are three implementations as follows: - * @see NoRegionSplitPointRestriction - * @see KeyPrefixRegionSplitPointRestriction - * @see DelimitedKeyPrefixRegionSplitPointRestriction + * @see NoRegionSplitRestriction + * @see KeyPrefixRegionSplitRestriction + * @see DelimitedKeyPrefixRegionSplitRestriction */ @InterfaceAudience.Private -public abstract class RegionSplitPointRestriction { - private static final Logger LOG = LoggerFactory.getLogger(RegionSplitPointRestriction.class); +public abstract class RegionSplitRestriction { + private static final Logger LOG = LoggerFactory.getLogger(RegionSplitRestriction.class); public static final String RESTRICTION_TYPE_KEY = - "hbase.regionserver.region.split_point_restriction.type"; + "hbase.regionserver.region.split_restriction.type"; public static final String RESTRICTION_TYPE_NONE = "None"; public static final String RESTRICTION_TYPE_KEY_PREFIX = "KeyPrefix"; public static final String RESTRICTION_TYPE_DELIMITED_KEY_PREFIX = "DelimitedKeyPrefix"; /** - * Create the RegionSplitPointRestriction configured for the given table. + * Create the RegionSplitRestriction configured for the given table. * * @param tableDescriptor the table descriptor * @param conf the configuration - * @return a RegionSplitPointRestriction instance + * @return a RegionSplitRestriction instance * @throws IOException if an error occurs */ - public static RegionSplitPointRestriction create(TableDescriptor tableDescriptor, + public static RegionSplitRestriction create(TableDescriptor tableDescriptor, Configuration conf) throws IOException { String type = tableDescriptor.getValue(RESTRICTION_TYPE_KEY); if (type == null) { type = conf.get(RESTRICTION_TYPE_KEY, RESTRICTION_TYPE_NONE); } - RegionSplitPointRestriction ret; + RegionSplitRestriction ret; switch (type) { case RESTRICTION_TYPE_NONE: - ret = new NoRegionSplitPointRestriction(); + ret = new NoRegionSplitRestriction(); break; case RESTRICTION_TYPE_KEY_PREFIX: - ret = new KeyPrefixRegionSplitPointRestriction(); + ret = new KeyPrefixRegionSplitRestriction(); break; case RESTRICTION_TYPE_DELIMITED_KEY_PREFIX: - ret = new DelimitedKeyPrefixRegionSplitPointRestriction(); + ret = new DelimitedKeyPrefixRegionSplitRestriction(); break; default: - LOG.warn("Invalid RegionSplitPointRestriction type specified: {}. " - + "Using the default RegionSplitPointRestriction", type); - ret = new NoRegionSplitPointRestriction(); + LOG.warn("Invalid RegionSplitRestriction type specified: {}. " + + "Using the default RegionSplitRestriction", type); + ret = new NoRegionSplitRestriction(); break; } ret.initialize(tableDescriptor, conf); @@ -80,7 +80,7 @@ public static RegionSplitPointRestriction create(TableDescriptor tableDescriptor } /** - * Initialize the RegionSplitPointRestriction instance + * Initialize the RegionSplitRestriction instance * * @param tableDescriptor the table descriptor * @param conf the configuration diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java deleted file mode 100644 index 640fcb7d342c..000000000000 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPointRestriction.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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.regionserver; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.HBaseClassTestRule; -import org.apache.hadoop.hbase.client.TableDescriptor; -import org.apache.hadoop.hbase.testclassification.RegionServerTests; -import org.apache.hadoop.hbase.testclassification.SmallTests; -import org.apache.hadoop.hbase.util.Bytes; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@Category({ RegionServerTests.class, SmallTests.class }) -public class TestRegionSplitPointRestriction { - - @ClassRule - public static final HBaseClassTestRule CLASS_RULE = - HBaseClassTestRule.forClass(TestRegionSplitPointRestriction.class); - - Configuration conf; - @Mock TableDescriptor tableDescriptor; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - - conf = new Configuration(); - } - - @Test - public void testWhenTableDescriptorReturnsNoneType() throws IOException { - when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) - .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_NONE); - - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof NoRegionSplitPointRestriction); - } - - @Test - public void testWhenTableDescriptorReturnsKeyPrefixType() throws IOException { - when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) - .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY_PREFIX); - - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof KeyPrefixRegionSplitPointRestriction); - } - - @Test - public void testWhenTableDescriptorReturnsDelimitedKeyPrefixType() throws IOException { - when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) - .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); - - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof DelimitedKeyPrefixRegionSplitPointRestriction); - } - - @Test - public void testWhenConfigurationReturnsNoneType() throws IOException { - conf.set(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY, - RegionSplitPointRestriction.RESTRICTION_TYPE_NONE); - - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof NoRegionSplitPointRestriction); - } - - @Test - public void testWhenConfigurationReturnsKeyPrefixType() throws IOException { - conf.set(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY, - RegionSplitPointRestriction.RESTRICTION_TYPE_KEY_PREFIX); - - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof KeyPrefixRegionSplitPointRestriction); - } - - @Test - public void testWhenConfigurationReturnsDelimitedKeyPrefixType() throws IOException { - conf.set(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY, - RegionSplitPointRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); - - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof DelimitedKeyPrefixRegionSplitPointRestriction); - } - - @Test - public void testWhenTableDescriptorAndConfigurationReturnNull() throws IOException { - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof NoRegionSplitPointRestriction); - } - - @Test - public void testWhenTableDescriptorReturnsInvalidType() throws IOException { - when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) - .thenReturn("Invalid"); - - RegionSplitPointRestriction splitPointRestriction = - RegionSplitPointRestriction.create(tableDescriptor, conf); - assertTrue(splitPointRestriction instanceof NoRegionSplitPointRestriction); - } - - @Test - public void testNoneRegionSplitPointRestriction() throws IOException { - when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) - .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_NONE); - - NoRegionSplitPointRestriction noRegionSplitPointRestriction = - (NoRegionSplitPointRestriction) RegionSplitPointRestriction.create(tableDescriptor, conf); - - byte[] restrictedSplitPoint = - noRegionSplitPointRestriction.getRestrictedSplitPoint(Bytes.toBytes("abcd")); - assertEquals("abcd", Bytes.toString(restrictedSplitPoint)); - } - - @Test - public void testKeyPrefixRegionSplitPointRestriction() throws IOException { - when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) - .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY_PREFIX); - when(tableDescriptor.getValue(KeyPrefixRegionSplitPointRestriction.PREFIX_LENGTH_KEY)) - .thenReturn("2"); - - KeyPrefixRegionSplitPointRestriction keyPrefixRegionSplitPointRestriction = - (KeyPrefixRegionSplitPointRestriction) RegionSplitPointRestriction.create( - tableDescriptor, conf); - - byte[] restrictedSplitPoint = - keyPrefixRegionSplitPointRestriction.getRestrictedSplitPoint(Bytes.toBytes("abcd")); - assertEquals("ab", Bytes.toString(restrictedSplitPoint)); - - restrictedSplitPoint = - keyPrefixRegionSplitPointRestriction.getRestrictedSplitPoint(Bytes.toBytes("a")); - assertEquals("a", Bytes.toString(restrictedSplitPoint)); - } - - @Test - public void testDelimitedKeyPrefixRegionSplitPointRestriction() throws IOException { - when(tableDescriptor.getValue(RegionSplitPointRestriction.RESTRICTION_TYPE_KEY)) - .thenReturn(RegionSplitPointRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); - when(tableDescriptor.getValue(DelimitedKeyPrefixRegionSplitPointRestriction.DELIMITER_KEY)) - .thenReturn(","); - - DelimitedKeyPrefixRegionSplitPointRestriction delimitedKeyPrefixRegionSplitPointRestriction = - (DelimitedKeyPrefixRegionSplitPointRestriction) RegionSplitPointRestriction.create( - tableDescriptor, conf); - - byte[] restrictedSplitPoint = delimitedKeyPrefixRegionSplitPointRestriction - .getRestrictedSplitPoint(Bytes.toBytes("ab,cd")); - assertEquals("ab", Bytes.toString(restrictedSplitPoint)); - - restrictedSplitPoint = delimitedKeyPrefixRegionSplitPointRestriction - .getRestrictedSplitPoint(Bytes.toBytes("ijk")); - assertEquals("ijk", Bytes.toString(restrictedSplitPoint)); - } -} diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitRestriction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitRestriction.java new file mode 100644 index 000000000000..329a7afa5ac0 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitRestriction.java @@ -0,0 +1,184 @@ +/* + * 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.regionserver; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.client.TableDescriptor; +import org.apache.hadoop.hbase.testclassification.RegionServerTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@Category({ RegionServerTests.class, SmallTests.class }) +public class TestRegionSplitRestriction { + + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestRegionSplitRestriction.class); + + Configuration conf; + @Mock TableDescriptor tableDescriptor; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + conf = new Configuration(); + } + + @Test + public void testWhenTableDescriptorReturnsNoneType() throws IOException { + when(tableDescriptor.getValue(RegionSplitRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitRestriction.RESTRICTION_TYPE_NONE); + + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + assertTrue(splitRestriction instanceof NoRegionSplitRestriction); + } + + @Test + public void testWhenTableDescriptorReturnsKeyPrefixType() throws IOException { + when(tableDescriptor.getValue(RegionSplitRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitRestriction.RESTRICTION_TYPE_KEY_PREFIX); + + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + assertTrue(splitRestriction instanceof KeyPrefixRegionSplitRestriction); + } + + @Test + public void testWhenTableDescriptorReturnsDelimitedKeyPrefixType() throws IOException { + when(tableDescriptor.getValue(RegionSplitRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); + + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + assertTrue(splitRestriction instanceof DelimitedKeyPrefixRegionSplitRestriction); + } + + @Test + public void testWhenConfigurationReturnsNoneType() throws IOException { + conf.set(RegionSplitRestriction.RESTRICTION_TYPE_KEY, + RegionSplitRestriction.RESTRICTION_TYPE_NONE); + + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + assertTrue(splitRestriction instanceof NoRegionSplitRestriction); + } + + @Test + public void testWhenConfigurationReturnsKeyPrefixType() throws IOException { + conf.set(RegionSplitRestriction.RESTRICTION_TYPE_KEY, + RegionSplitRestriction.RESTRICTION_TYPE_KEY_PREFIX); + + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + assertTrue(splitRestriction instanceof KeyPrefixRegionSplitRestriction); + } + + @Test + public void testWhenConfigurationReturnsDelimitedKeyPrefixType() throws IOException { + conf.set(RegionSplitRestriction.RESTRICTION_TYPE_KEY, + RegionSplitRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); + + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + assertTrue(splitRestriction instanceof DelimitedKeyPrefixRegionSplitRestriction); + } + + @Test + public void testWhenTableDescriptorAndConfigurationReturnNull() throws IOException { + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + assertTrue(splitRestriction instanceof NoRegionSplitRestriction); + } + + @Test + public void testWhenTableDescriptorReturnsInvalidType() throws IOException { + when(tableDescriptor.getValue(RegionSplitRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn("Invalid"); + + RegionSplitRestriction splitRestriction = + RegionSplitRestriction.create(tableDescriptor, conf); + assertTrue(splitRestriction instanceof NoRegionSplitRestriction); + } + + @Test + public void testNoneRegionSplitRestriction() throws IOException { + when(tableDescriptor.getValue(RegionSplitRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitRestriction.RESTRICTION_TYPE_NONE); + + NoRegionSplitRestriction noRegionSplitRestriction = + (NoRegionSplitRestriction) RegionSplitRestriction.create(tableDescriptor, conf); + + byte[] restrictedSplit = + noRegionSplitRestriction.getRestrictedSplitPoint(Bytes.toBytes("abcd")); + assertEquals("abcd", Bytes.toString(restrictedSplit)); + } + + @Test + public void testKeyPrefixRegionSplitRestriction() throws IOException { + when(tableDescriptor.getValue(RegionSplitRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitRestriction.RESTRICTION_TYPE_KEY_PREFIX); + when(tableDescriptor.getValue(KeyPrefixRegionSplitRestriction.PREFIX_LENGTH_KEY)) + .thenReturn("2"); + + KeyPrefixRegionSplitRestriction keyPrefixRegionSplitRestriction = + (KeyPrefixRegionSplitRestriction) RegionSplitRestriction.create( + tableDescriptor, conf); + + byte[] restrictedSplit = + keyPrefixRegionSplitRestriction.getRestrictedSplitPoint(Bytes.toBytes("abcd")); + assertEquals("ab", Bytes.toString(restrictedSplit)); + + restrictedSplit = + keyPrefixRegionSplitRestriction.getRestrictedSplitPoint(Bytes.toBytes("a")); + assertEquals("a", Bytes.toString(restrictedSplit)); + } + + @Test + public void testDelimitedKeyPrefixRegionSplitRestriction() throws IOException { + when(tableDescriptor.getValue(RegionSplitRestriction.RESTRICTION_TYPE_KEY)) + .thenReturn(RegionSplitRestriction.RESTRICTION_TYPE_DELIMITED_KEY_PREFIX); + when(tableDescriptor.getValue(DelimitedKeyPrefixRegionSplitRestriction.DELIMITER_KEY)) + .thenReturn(","); + + DelimitedKeyPrefixRegionSplitRestriction delimitedKeyPrefixRegionSplitRestriction = + (DelimitedKeyPrefixRegionSplitRestriction) RegionSplitRestriction.create( + tableDescriptor, conf); + + byte[] restrictedSplit = delimitedKeyPrefixRegionSplitRestriction + .getRestrictedSplitPoint(Bytes.toBytes("ab,cd")); + assertEquals("ab", Bytes.toString(restrictedSplit)); + + restrictedSplit = delimitedKeyPrefixRegionSplitRestriction + .getRestrictedSplitPoint(Bytes.toBytes("ijk")); + assertEquals("ijk", Bytes.toString(restrictedSplit)); + } +} From b6006d736dddb15daa899881240e9c1edc11e4da Mon Sep 17 00:00:00 2001 From: Toshihiro Suzuki Date: Tue, 20 Apr 2021 21:50:22 +0900 Subject: [PATCH 5/7] Fix the checkstyle error --- .../hbase/master/assignment/SplitTableRegionProcedure.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java index b0fa05c9a42d..cc9732f69153 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java @@ -61,8 +61,8 @@ import org.apache.hadoop.hbase.regionserver.HRegionFileSystem; import org.apache.hadoop.hbase.regionserver.HStore; import org.apache.hadoop.hbase.regionserver.HStoreFile; -import org.apache.hadoop.hbase.regionserver.RegionSplitRestriction; import org.apache.hadoop.hbase.regionserver.RegionSplitPolicy; +import org.apache.hadoop.hbase.regionserver.RegionSplitRestriction; import org.apache.hadoop.hbase.regionserver.StoreFileInfo; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.CommonFSUtils; From c6bfe5dab696cec109b4a204885f51d2d69d03eb Mon Sep 17 00:00:00 2001 From: Toshihiro Suzuki Date: Wed, 21 Apr 2021 09:41:00 +0900 Subject: [PATCH 6/7] Add some JavaDoc for RegionSplitRestriction --- .../DelimitedKeyPrefixRegionSplitRestriction.java | 4 ++-- .../hbase/regionserver/KeyPrefixRegionSplitRestriction.java | 2 +- .../hadoop/hbase/regionserver/NoRegionSplitRestriction.java | 2 +- .../hadoop/hbase/regionserver/RegionSplitRestriction.java | 4 ++++ 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java index ebdd0c00299f..2491ab48ead0 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java @@ -27,8 +27,8 @@ import org.slf4j.LoggerFactory; /** - * A RegionSplitRestriction implementation that groups rows by a prefix of the row-key with a - * delimiter. Only the first delimiter for the row key will define the prefix of the row key that + * A {@link RegionSplitRestriction} implementation that groups rows by a prefix of the row-key with + * a delimiter. Only the first delimiter for the row key will define the prefix of the row key that * is used for grouping. * * This ensures that a region is not split "inside" a prefix of a row key. diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java index 627722bee0d8..3d3be6fc4814 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; /** - * A RegionSplitRestriction implementation that groups rows by a prefix of the row-key. + * A {@link RegionSplitRestriction} implementation that groups rows by a prefix of the row-key. * * This ensures that a region is not split "inside" a prefix of a row key. * I.e. rows can be co-located in a region by their prefix. diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitRestriction.java index 6e5969ef7e3a..662c164b3a63 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoRegionSplitRestriction.java @@ -23,7 +23,7 @@ import org.apache.yetus.audience.InterfaceAudience; /** - * A RegionSplitRestriction implementation that does nothing. + * A {@link RegionSplitRestriction} implementation that does nothing. */ @InterfaceAudience.Private public class NoRegionSplitRestriction extends RegionSplitRestriction { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java index 64bf94f55d10..07b24d4c560b 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java @@ -27,6 +27,10 @@ /** * A split restriction that restricts the pattern of the split point. * + * The difference between {@link RegionSplitPolicy} and RegionSplitRestriction is that + * RegionSplitRestriction defines how to split while {@link RegionSplitPolicy} defines when we need + * to split. + * * There are three implementations as follows: * @see NoRegionSplitRestriction * @see KeyPrefixRegionSplitRestriction From 819e25a8955ef209b5ba543a818a44d072e09d02 Mon Sep 17 00:00:00 2001 From: Toshihiro Suzuki Date: Wed, 21 Apr 2021 14:42:02 +0900 Subject: [PATCH 7/7] Add a WARN message and some JavaDoc --- .../assignment/SplitTableRegionProcedure.java | 8 ++++- ...imitedKeyPrefixRegionSplitRestriction.java | 2 +- .../KeyPrefixRegionSplitRestriction.java | 2 +- .../regionserver/RegionSplitRestriction.java | 29 +++++++++++++++++-- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java index cc9732f69153..09ac8274bf2a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java @@ -118,7 +118,13 @@ public SplitTableRegionProcedure(final MasterProcedureEnv env, // Apply the split restriction for the table to the user-specified split point RegionSplitRestriction splitRestriction = RegionSplitRestriction.create(tableDescriptor, conf); - bestSplitRow = splitRestriction.getRestrictedSplitPoint(bestSplitRow); + byte[] restrictedSplitRow = splitRestriction.getRestrictedSplitPoint(bestSplitRow); + if (!Bytes.equals(bestSplitRow, restrictedSplitRow)) { + LOG.warn("The specified split point {} violates the split restriction of the table. " + + "Using {} as a split point.", Bytes.toStringBinary(bestSplitRow), + Bytes.toStringBinary(restrictedSplitRow)); + bestSplitRow = restrictedSplitRow; + } } checkSplittable(env, regionToSplit); final TableName table = regionToSplit.getTable(); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java index 2491ab48ead0..fa686489bbe1 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DelimitedKeyPrefixRegionSplitRestriction.java @@ -30,7 +30,7 @@ * A {@link RegionSplitRestriction} implementation that groups rows by a prefix of the row-key with * a delimiter. Only the first delimiter for the row key will define the prefix of the row key that * is used for grouping. - * + *

* This ensures that a region is not split "inside" a prefix of a row key. * I.e. rows can be co-located in a region by their prefix. * diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java index 3d3be6fc4814..41fcc2a86216 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitRestriction.java @@ -27,7 +27,7 @@ /** * A {@link RegionSplitRestriction} implementation that groups rows by a prefix of the row-key. - * + *

* This ensures that a region is not split "inside" a prefix of a row key. * I.e. rows can be co-located in a region by their prefix. */ diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java index 07b24d4c560b..3a1925cf54db 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionSplitRestriction.java @@ -26,12 +26,37 @@ /** * A split restriction that restricts the pattern of the split point. - * + *

* The difference between {@link RegionSplitPolicy} and RegionSplitRestriction is that * RegionSplitRestriction defines how to split while {@link RegionSplitPolicy} defines when we need * to split. + *

+ * We can specify a split restriction, "KeyPrefix" or "DelimitedKeyPrefix", to a table with the + * "hbase.regionserver.region.split_restriction.type" property. The "KeyPrefix" split restriction + * groups rows by a prefix of the row-key. And the "DelimitedKeyPrefix" split restriction groups + * rows by a prefix of the row-key with a delimiter. + * + * For example: + *

+ * 
+ * # Create a table with a "KeyPrefix" split restriction, where the prefix length is 2 bytes
+ * hbase> create 'tbl1', 'fam',
+ *   {CONFIGURATION => {'hbase.regionserver.region.split_restriction.type' => 'KeyPrefix',
+ *                      'hbase.regionserver.region.split_restriction.prefix_length' => '2'}}
+ *
+ * # Create a table with a "DelimitedKeyPrefix" split restriction, where the delimiter is a comma
+ * hbase> create 'tbl2', 'fam',
+ *   {CONFIGURATION => {'hbase.regionserver.region.split_restriction.type' => 'DelimitedKeyPrefix',
+ *                      'hbase.regionserver.region.split_restriction.delimiter' => ','}}
+ * 
+ * 
+ * + * Instead of specifying a split restriction to a table directly, we can also set the properties + * in hbase-site.xml. In this case, the specified split restriction is applied for all the tables. + *

+ * Note that the split restriction is also applied to a user-specified split point so that we don't + * allow users to break the restriction. * - * There are three implementations as follows: * @see NoRegionSplitRestriction * @see KeyPrefixRegionSplitRestriction * @see DelimitedKeyPrefixRegionSplitRestriction