Rowkeys与Region Split之间的关系

Rowkeys与Region Split之间的关系

⚠️如果你在创建表的时候进行了预分区,那么弄清楚你的rowkey对应的数据会分布在region区间内是十分客观重要的!⚠️

1 为啥重要?

Hbase Region split图解

让我们看一个例子,考虑将可以展示的字符的16进制值的作为rowkey所在region的的Start-Key,Start-Key范围从(“0000000000000000” to “ffffffffffffffff”),通过Bytes.split方法运行这些rowkey范围,这个方法是在使用Admin.createTable(byte[] startKey, byte[] endKey, numRegions)创建region的时候的一种默认策略,对于10个region将会生成以下不同的region切片。

48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48                                // 0
54 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10                 // 6
61 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -68                 // =
68 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -126  // D
75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 72                                // K
82 18 18 18 18 18 18 18 18 18 18 18 18 18 18 14                                // R
88 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -44                 // X
95 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -102                // _
102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102                // f
  • 注意分区region起始位置(Start-Key)字符列在内容的右边,第一个片是’0’,最后的region split是‘f’,所有的事情都看起来十分完美是不是?不要下定义这么早!
    • 问题来了,所有的数据将会堆积在前2个region以及最后的region中最后造成 ‘hot’ 或者叫做 ‘lumpy’ 的region问题⚠️
    • 为什么会这样呢,0是字节48,而f是字节102,但是字节值(58-96)之间存在巨大的差异,(58-96)该区域间隙永远不会出现在这个keyspace中,因为只有[0-9],[a-f]会出现在该键控范围,因此中间的region永远使用不到,所以用户自定义预分区是非常有必要的,我们不要依赖Hbase内置的region split方法。
    • 最终我们要让我们的所有数据尽可能落在我们的创建的region范围内

2 预分区的正确操作姿势

  • 预分区通常是个很好的尝试,但是你需要让所有的regions在rowkeys的键控范围内都能被访问到,不然你的建的region都是垃圾region,根本用不着,以上的示范案例只呈现了16进制键控空间出现的问题,同样的问题可能会出现在其它的keyspace,设计的时候请了解自己的数据。
  • 官方不建议使用16进制数据作为rowkey的同时还进行预分区设计,更常用的是将显示的数据拼接成rowkey,然后按照这些rowkey进行预分区。

以下案例代码教你如何正确为16进制的rowkey进行预分区。

public static boolean createTable(Admin 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;
}

感谢大家!~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值