开发者学堂课程【HBase 入门教程:HBase 优化_1】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/397/detail/5093
HBase 优化_1
一、 Pre-Creating Regions
默认情况下,在创建 HBase 表的时候会自动创建-个 region 分区,当导入数据的时候,所有的 HBase 客户端都向这一个 region 写数据,直到这个 region 足够大了才进行切分。一种可以加快批量写入速度的方法是通过预先创建一些空的 regions ,这样当数据写入 HBase 时,会按照 region 分区情况,在集群内做数据的负载均衡。
public static boolean createTable(HBaseAdmin admin, HTableDescriptor table, byte[][]splits)
throws IOException {
try {
admin.createTable(table, splits);
return true;
} catch (TableExistsException e) {
logger.info("table " + table.getNameAsString() + " already exists");
// the table already exists...
return false;
}
}
有关预分区,详情参见:Table Creation: Pre-Creating Regions,下面是一个例子:
public static boolean createTable(HBaseAdmin admin,HTableDescriptor table,byte[][]splits)
throws IOException {
try {
admin.createTable(table, splits);
return true;
} catch (TableExistsException e) {
logger.info("table " + table.getNameAsString() + " already exists");
// the table already exists...
return false;
}
}
public static byte[][] getHexSplits(String startKey, String endKey, int numRegions) {
byte[][] splits = new byte[numRegions-1][];
BigInteger lowestKey = new BigInteger(startKey, 16);
BigInteger highestKey = new BigInteger(endKey, 16);
BigInteger range = highestKey.subtract(lowestKey);
BigInteger regionIncrement = range.divide(BigInteger.valueOf(numRegions));
lowestKey = lowestKey.add(regionIncrement);
for(int i=0; i < numRegions-1;i++) {
BigInteger key = lowestKey.add(regionIncrement.multiply(BigInteger.valueOf(i)));
byte[] b = String.format("%016x", key).getBytes();
splits[i] = b;
}
return splits;
}
二、Row Key
HBase 中 row key 用来检索表中的记录,支持以下三种方式:
1. 通过单个 row key 访问:即按照某个 row key 键值进行 get 操作;
2. 通过 rowkey 的 range 进行 scan:即通过设置 startRowKey 和 endRowKey ,在这个范围内进行扫描;
3. 全表扫描:即直接扫描整张表中所有行记录。
在 HBase 中,row key 可以是任意字符串,最大长度64KB,实际应用中一般为10~100bytes,存为 byte[] 字节数组,一般设计成定长的。
row key 是按照字典序存储,因此,设计 row key 时,要充分利用这个排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放在一块。
举个例子:如果最近写入 HBase 表中的数据是最可能被访问的,可以考虑将时间戳作为 row key 的一部分,由于是字典序排序,所以可以使用 Long.MAX_VALUE - timestamp 作为 row key ,这样能保证新写入的数据在读取时可以被快速命中。