导读:本文介绍如何使用hbase自带的HexStringSplit算法,根据传入参数(最小值、最大值、分区数量)生成startKey,endKey为16进制表示的region。
RegionSplitter.HexStringSplit()自带的默认最小最大keySpace表示如下:
final static String DEFAULT_MIN_HEX = "00000000";
final static String DEFAULT_MAX_HEX = "FFFFFFFF";
但我们需要根据记录中的数值范围进行定制keySpace值的上下限,避免创建出rowkey无法访问的region。
/**
* 生成用于创建分区表的rowKey字节数组,数组中每个值都是十六进制字符表
*
* @param regionNum 期望的分区数量
* @param startIndex 当前系统的最小值(可忽略独立单条最小值,取接近众数的最小值)
* @param endIndex 为系统的最大值(可忽略独立单条最大值,取接近众数的最大值)
* @return splits 用于创建分区表的rowKey数组
* */
public byte[][] hexSplit(int regionNum, BigInteger startIndex, BigInteger endIndex) throws IOException {
RegionSplitter.SplitAlgorithm algo = new RegionSplitter.HexStringSplit();
algo.setFirstRow(startIndex.toString(16));
algo.setLastRow(endIndex.toString(16));
byte[][] splits = algo.split(regionNum);
return splits;
}
/**
* 使用16进制的字符表示key space中的startKey、endKey,对数值区间进行均匀划分
* */
public void createTableByHexStringSplit() throws IOException {
Connection connection = getConnection();
Admin admin = connection.getAdmin();
HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(namespaceAsString + ":" + tableName));
desc.addFamily(new HColumnDescriptor(familyName));
//startIndex为业务中的最小index
BigInteger startIndex=BigInteger.valueOf(0L);
//endIndex为业务中的最大index
BigInteger endIndex=BigInteger.valueOf(2147483647);
//分区的数量
int regionNum=16;
byte[][] splits = hexSplit(regionNum,startIndex,endIndex);
admin.createTable(desc, splits);
}
region分布以8位的16进制进行key space表示:
key会根据endIndex的16进制字符长度对较短字符使用“0”进行补充。例如:第一个region的end key为“08000000”,第一个字符“0”为填充,让整个key满足8位。
如果觉得21亿多(2147483647)的数值仍然不能满足rowkey的表示,可以使用long类型的endIndex来表示,以生成更多位数的十六进制表示。
//startIndex为业务中的最小index
BigInteger startIndex=BigInteger.valueOf(0L);
//endIndex为业务中的最大index,假设为Long.MAX_VALUE,
//long MAX_VALUE = 0x7fffffffffffffffL;
BigInteger endIndex=BigInteger.valueOf(9223372036854775807L);
//分区的数量
int regionNum=16;
region分布以16位的16进制进行key space表示:
如何生成rowkey或rowkey前缀?
** **将要插入的index(作为rowkey或rowkey前缀)生成16进制表示的字符串。
//long类型
BigInteger rowkeyPrefix = BigInteger.valueOf(9223372036854775807L);
//or int类型
BigInteger rowkeyPrefix = BigInteger.valueOf(2147483647);
总结:
- 如果做为rowkey前缀的id本身具有自增特性且连续,可以对id直接进行区间划分,但要考虑id自增的速度,是提前预留分区还是后期手动split region。
- 此key space分区不适用于反转index的方式。例如,反转21474为47421。