HBASE-19703 Functionality added as part of HBASE-12583 is not working after moving the split code to master

Co-authored-by: Michael Stack <stack@apache.org>

Signed-off-by: Chia-Ping Tsai <chia7712@gmail.com>
This commit is contained in:
Rajeshbabu Chintaguntla 2018-02-05 23:35:32 +08:00 committed by Chia-Ping Tsai
parent 514eadbe95
commit f0a5f12d97
4 changed files with 42 additions and 16 deletions

View File

@ -32,7 +32,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
@ -63,16 +62,20 @@ import org.apache.hadoop.hbase.quotas.QuotaExceededException;
import org.apache.hadoop.hbase.regionserver.HRegionFileSystem; import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
import org.apache.hadoop.hbase.regionserver.HStore; import org.apache.hadoop.hbase.regionserver.HStore;
import org.apache.hadoop.hbase.regionserver.HStoreFile; import org.apache.hadoop.hbase.regionserver.HStoreFile;
import org.apache.hadoop.hbase.regionserver.RegionSplitPolicy;
import org.apache.hadoop.hbase.regionserver.StoreFileInfo; import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.FSUtils; import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.hbase.util.Threads; import org.apache.hadoop.hbase.util.Threads;
import org.apache.hadoop.util.ReflectionUtils;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos;
@ -91,6 +94,8 @@ public class SplitTableRegionProcedure
private RegionInfo daughter_1_RI; private RegionInfo daughter_1_RI;
private RegionInfo daughter_2_RI; private RegionInfo daughter_2_RI;
private byte[] bestSplitRow; private byte[] bestSplitRow;
private TableDescriptor htd;
private RegionSplitPolicy splitPolicy;
public SplitTableRegionProcedure() { public SplitTableRegionProcedure() {
// Required by the Procedure framework to create the procedure on replay // Required by the Procedure framework to create the procedure on replay
@ -115,6 +120,16 @@ public class SplitTableRegionProcedure
.setSplit(false) .setSplit(false)
.setRegionId(rid) .setRegionId(rid)
.build(); .build();
this.htd = env.getMasterServices().getTableDescriptors().get(getTableName());
if(this.htd.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<? extends RegionSplitPolicy> clazz =
RegionSplitPolicy.getSplitPolicyClass(this.htd, env.getMasterConfiguration());
this.splitPolicy = ReflectionUtils.newInstance(clazz, env.getMasterConfiguration());
}
} }
/** /**
@ -597,7 +612,6 @@ public class SplitTableRegionProcedure
final List<Future<Pair<Path,Path>>> futures = new ArrayList<Future<Pair<Path,Path>>>(nbFiles); final List<Future<Pair<Path,Path>>> futures = new ArrayList<Future<Pair<Path,Path>>>(nbFiles);
// Split each store file. // Split each store file.
final TableDescriptor htd = env.getMasterServices().getTableDescriptors().get(getTableName());
for (Map.Entry<String, Collection<StoreFileInfo>>e: files.entrySet()) { for (Map.Entry<String, Collection<StoreFileInfo>>e: files.entrySet()) {
byte [] familyName = Bytes.toBytes(e.getKey()); byte [] familyName = Bytes.toBytes(e.getKey());
final ColumnFamilyDescriptor hcd = htd.getColumnFamily(familyName); final ColumnFamilyDescriptor hcd = htd.getColumnFamily(familyName);
@ -676,10 +690,10 @@ public class SplitTableRegionProcedure
final byte[] splitRow = getSplitRow(); final byte[] splitRow = getSplitRow();
final String familyName = Bytes.toString(family); final String familyName = Bytes.toString(family);
final Path path_first = final Path path_first = regionFs.splitStoreFile(this.daughter_1_RI, familyName, sf, splitRow,
regionFs.splitStoreFile(this.daughter_1_RI, familyName, sf, splitRow, false, null); false, splitPolicy);
final Path path_second = final Path path_second = regionFs.splitStoreFile(this.daughter_2_RI, familyName, sf, splitRow,
regionFs.splitStoreFile(this.daughter_2_RI, familyName, sf, splitRow, true, null); true, splitPolicy);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("pid=" + getProcId() + " splitting complete for store file: " + LOG.debug("pid=" + getProcId() + " splitting complete for store file: " +
sf.getPath() + " for region: " + getParentRegion().getShortNameToLog()); sf.getPath() + " for region: " + getParentRegion().getShortNameToLog());

View File

@ -652,7 +652,9 @@ public class HRegionFileSystem {
* @param f File to split. * @param f File to split.
* @param splitRow Split Row * @param splitRow Split Row
* @param top True if we are referring to the top half of the hfile. * @param top True if we are referring to the top half of the hfile.
* @param splitPolicy * @param splitPolicy A split policy instance; be careful! May not be full populated; e.g. if
* this method is invoked on the Master side, then the RegionSplitPolicy will
* NOT have a reference to a Region.
* @return Path to created reference. * @return Path to created reference.
* @throws IOException * @throws IOException
*/ */

View File

@ -28,12 +28,12 @@ import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.util.ReflectionUtils; import org.apache.hadoop.util.ReflectionUtils;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
/** /**
* A split policy determines when a region should be split. * A split policy determines when a Region should be split.
*
* @see SteppingSplitPolicy Default split policy since 2.0.0 * @see SteppingSplitPolicy Default split policy since 2.0.0
* @see IncreasingToUpperBoundRegionSplitPolicy Default split policy since * @see IncreasingToUpperBoundRegionSplitPolicy Default split policy since
* 0.94.0 * 0.94.0
@ -46,6 +46,9 @@ public abstract class RegionSplitPolicy extends Configured {
/** /**
* The region configured for this split policy. * The region configured for this split policy.
* As of hbase-2.0.0, RegionSplitPolicy can be instantiated on the Master-side so the
* Phoenix local-indexer can block default hbase behavior. This is an exotic usage. Should not
* trouble any other users of RegionSplitPolicy.
*/ */
protected HRegion region; protected HRegion region;
@ -103,6 +106,7 @@ public abstract class RegionSplitPolicy extends Configured {
*/ */
public static RegionSplitPolicy create(HRegion region, public static RegionSplitPolicy create(HRegion region,
Configuration conf) throws IOException { Configuration conf) throws IOException {
Preconditions.checkNotNull(region, "Region should not be null.");
Class<? extends RegionSplitPolicy> clazz = getSplitPolicyClass( Class<? extends RegionSplitPolicy> clazz = getSplitPolicyClass(
region.getTableDescriptor(), conf); region.getTableDescriptor(), conf);
RegionSplitPolicy policy = ReflectionUtils.newInstance(clazz, conf); RegionSplitPolicy policy = ReflectionUtils.newInstance(clazz, conf);
@ -133,11 +137,17 @@ public abstract class RegionSplitPolicy extends Configured {
/** /**
* In {@link HRegionFileSystem#splitStoreFile(org.apache.hadoop.hbase.client.RegionInfo, String, * In {@link HRegionFileSystem#splitStoreFile(org.apache.hadoop.hbase.client.RegionInfo, String,
* HStoreFile, byte[], boolean, RegionSplitPolicy)} we are not creating the split reference * HStoreFile, byte[], boolean, RegionSplitPolicy)} we are not creating the split reference
* if split row not lies in the StoreFile range. But in some use cases we may need to create * if split row does not lie inside the StoreFile range. But in some use cases we may need to
* the split reference even when the split row not lies in the range. This method can be used * create the split reference even when the split row does not lie inside the StoreFile range.
* to decide, whether to skip the the StoreFile range check or not. * This method can be used to decide, whether to skip the the StoreFile range check or not.
* @return whether to skip the StoreFile range check or not *
* @param familyName * <p>This method is not for general use. It is a mechanism put in place by Phoenix
* local indexing to defeat standard hbase behaviors. Phoenix local indices are very likely
* the only folks who would make use of this method. On the Master-side, we will instantiate
* a RegionSplitPolicy instance and run this method ONLY... none of the others make sense
* on the Master-side.</p>
*
* TODO: Shutdown this phoenix specialization or do it via some other means.
* @return whether to skip the StoreFile range check or not * @return whether to skip the StoreFile range check or not
*/ */
protected boolean skipStoreFileRangeCheck(String familyName) { protected boolean skipStoreFileRangeCheck(String familyName) {

View File

@ -990,7 +990,7 @@ public class TestSplitTransactionOnCluster {
} }
} }
static class CustomSplitPolicy extends RegionSplitPolicy { static class CustomSplitPolicy extends IncreasingToUpperBoundRegionSplitPolicy {
@Override @Override
protected boolean shouldSplit() { protected boolean shouldSplit() {