预分区特性
Hbase中的表会被划分为n个Region,然后存放在多个RegionServer中,每个Region有StartKey和EndKey,表示这个Region维护的RowKey范围,而第一个Region没有StartKey,最后一个Region没有EndKey。需要读写数据时,RowKey会落在某个范围内,就会定位到目标的Region以及所在的RegionServer。
默认情况下,创建表的时候只有一个Region,当表的数据增长,数据大小大于一定的阈值,HBase就会找到一个MidKey将Region一分为二,这个过程被称为Region-Split,而Split是有时间和资源开销的。
随机散列与预分区
1.通过随机取样随机生成一定数量的RowKey,将取样数据按升序排序放到一个集合里
2.根据预分区的Region个数,对集合进行平均切割
3.HBaseAdmin.createTable(HTableDescriptor tableDescriptor,byte[][] splitkeys)可以指定预分区的splitKey,即是指定region间的rowkey临界值.
Java实现
两个接口
package com.test.HBasePrepartition;
public interface RowKeyGenerator {
byte[] nextId();
}
package com.test.HBasePrepartition;
//createTable(HTableDescriptor desc, byte[][] splitKeys),所以要建二维数组
public interface SplitKeysCalculator {
public byte[][] calcSplitKeys();
}
RowKey的生成
package com.test.HBasePrepartition;
import java.util.Random;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.MD5Hash;
public class HashRowKeyGenerator implements RowKeyGenerator {
private long currentId = 1;
private long currentTime = System.currentTimeMillis();
private Random random = new Random();
public byte[] nextId() {
try {
currentTime += random.nextInt(1000);
//从偏移量第4位开始取长度为4作为byte数组返回
byte[] lowT = Bytes.copy(Bytes.toBytes(currentTime), 4, 4);
byte[] lowU = Bytes.copy(Bytes.toBytes(currentId), 4, 4);
//拼装成一个byte数组
return Bytes.add(MD5Hash.getMD5AsHex(Bytes.add(lowU, lowT)).substring(0, 8).getBytes(),Bytes.toBytes(currentId));
} finally {
//ID递增
currentId+