001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.regionserver; 019 020import java.io.IOException; 021import org.apache.hadoop.conf.Configuration; 022import org.apache.hadoop.hbase.client.TableDescriptor; 023import org.apache.yetus.audience.InterfaceAudience; 024import org.slf4j.Logger; 025import org.slf4j.LoggerFactory; 026 027/** 028 * A split restriction that restricts the pattern of the split point. 029 * <p> 030 * The difference between {@link RegionSplitPolicy} and RegionSplitRestriction is that 031 * RegionSplitRestriction defines how to split while {@link RegionSplitPolicy} defines when we need 032 * to split. 033 * <p> 034 * We can specify a split restriction, "KeyPrefix" or "DelimitedKeyPrefix", to a table with the 035 * "hbase.regionserver.region.split_restriction.type" property. The "KeyPrefix" split restriction 036 * groups rows by a prefix of the row-key. And the "DelimitedKeyPrefix" split restriction groups 037 * rows by a prefix of the row-key with a delimiter. For example: 038 * 039 * <pre> 040 * <code> 041 * # Create a table with a "KeyPrefix" split restriction, where the prefix length is 2 bytes 042 * hbase> create 'tbl1', 'fam', 043 * {CONFIGURATION => {'hbase.regionserver.region.split_restriction.type' => 'KeyPrefix', 044 * 'hbase.regionserver.region.split_restriction.prefix_length' => '2'}} 045 * 046 * # Create a table with a "DelimitedKeyPrefix" split restriction, where the delimiter is a comma 047 * hbase> create 'tbl2', 'fam', 048 * {CONFIGURATION => {'hbase.regionserver.region.split_restriction.type' => 'DelimitedKeyPrefix', 049 * 'hbase.regionserver.region.split_restriction.delimiter' => ','}} 050 * </code> 051 * </pre> 052 * 053 * Instead of specifying a split restriction to a table directly, we can also set the properties in 054 * hbase-site.xml. In this case, the specified split restriction is applied for all the tables. 055 * <p> 056 * Note that the split restriction is also applied to a user-specified split point so that we don't 057 * allow users to break the restriction. 058 * @see NoRegionSplitRestriction 059 * @see KeyPrefixRegionSplitRestriction 060 * @see DelimitedKeyPrefixRegionSplitRestriction 061 */ 062@InterfaceAudience.Private 063public abstract class RegionSplitRestriction { 064 private static final Logger LOG = LoggerFactory.getLogger(RegionSplitRestriction.class); 065 066 public static final String RESTRICTION_TYPE_KEY = 067 "hbase.regionserver.region.split_restriction.type"; 068 069 public static final String RESTRICTION_TYPE_NONE = "None"; 070 public static final String RESTRICTION_TYPE_KEY_PREFIX = "KeyPrefix"; 071 public static final String RESTRICTION_TYPE_DELIMITED_KEY_PREFIX = "DelimitedKeyPrefix"; 072 073 /** 074 * Create the RegionSplitRestriction configured for the given table. 075 * @param tableDescriptor the table descriptor 076 * @param conf the configuration 077 * @return a RegionSplitRestriction instance 078 * @throws IOException if an error occurs 079 */ 080 public static RegionSplitRestriction create(TableDescriptor tableDescriptor, Configuration conf) 081 throws IOException { 082 String type = tableDescriptor.getValue(RESTRICTION_TYPE_KEY); 083 if (type == null) { 084 type = conf.get(RESTRICTION_TYPE_KEY, RESTRICTION_TYPE_NONE); 085 } 086 087 RegionSplitRestriction ret; 088 switch (type) { 089 case RESTRICTION_TYPE_NONE: 090 ret = new NoRegionSplitRestriction(); 091 break; 092 case RESTRICTION_TYPE_KEY_PREFIX: 093 ret = new KeyPrefixRegionSplitRestriction(); 094 break; 095 case RESTRICTION_TYPE_DELIMITED_KEY_PREFIX: 096 ret = new DelimitedKeyPrefixRegionSplitRestriction(); 097 break; 098 default: 099 LOG.warn("Invalid RegionSplitRestriction type specified: {}. " 100 + "Using the default RegionSplitRestriction", type); 101 ret = new NoRegionSplitRestriction(); 102 break; 103 } 104 ret.initialize(tableDescriptor, conf); 105 return ret; 106 } 107 108 /** 109 * Initialize the RegionSplitRestriction instance 110 * @param tableDescriptor the table descriptor 111 * @param conf the configuration 112 * @throws IOException if an error occurs 113 */ 114 public abstract void initialize(TableDescriptor tableDescriptor, Configuration conf) 115 throws IOException; 116 117 /** 118 * Returns a restricted split point. 119 * @param splitPoint the split point determined by {@link RegionSplitPolicy} or specified by a 120 * user manually 121 * @return the restricted split point 122 */ 123 public abstract byte[] getRestrictedSplitPoint(byte[] splitPoint); 124}