HBase优化之预分区

Posted HBase技术社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HBase优化之预分区相关的知识,希望对你有一定的参考价值。

    如果在hbase shell中使用create建表时只写了表名和列族名,那么这张表将只有一个region ,当一个region的大小超过阈值时会自动split成两个,但split操作会带来资源消耗。region个数太少时,在数据量大、访问量大,或被批处理程序读写情况下性能可能会很差,并且伴随大批量读写而来的GC可能会使regionserver宕机,接着region被transit到其他节点上,将逐步拖垮HBase集群上的所有节点。
    所以推荐在建表时进行预分区,充分考虑rowkey的分布做出合理的预分区方案,要考虑的点包括region的个数、region的大小等。

Region的个数

    如果使用MapReduce读取HBase表数据,Map的个数等于该表region的个数,每个region都会有一个单独进程来处理,这个进程会逐条处理region中的每一行数据。举例来说如果只有一个region,那么读取数据的就只有一个进程;如果拆成10个数据均匀分布的region,那么10个map会带来10倍的效率提升。
    大数据量情况下越发需要并行处理,因此我们往往希望源表的region的个数多一些。但是同时也要考虑集群的承载能力,HBase的region个数上限可以参考官网给出的如下公式,其中RS Xmx是regionserver的内存堆栈大小,官网建议每台20~24或更小,因为过大的内存会导致GC时间过长(GC方式从CMS改为G1后可以增大该值,机器内存足够的情况下可以翻倍甚至更大)。
((RS Xmx) *hbase.regionserver.global.memstore.size) / (hbase.hregion.memstore.flush.size *(# column families))。
    即24G*0.45/128M=86.4个,在实际使用中很容易超过这个值。另外官网建议每个RS 20~200个regions是比较合理的。因此region个数也不是越多越好,还要考虑集群情况。我们可以在HBase WebUI上看到这个值。

    对于不需要用MR批量读HBase表,相比需要MR读的表region个数可以少一些,以此来控制regionserver上region总数。 

Region的大小

    单个region最大大小官方推荐5~10GB,这是三备份前的数据大小,通过hbase.hregion.max.filesize配置,当超过这个值后region会split,估计好数据量并合理的划分region会减少不必要的性能损失。甚至设置足够大的值,日常监控中发现过大后手工做split。

预分区的方法

    预建region可以在shell中或者程序中实现,网上很多文章,如下是一些例子,不再赘述。要想清楚rowkey的边界,比如对于全部都是数字开头的rowkey,分200个region,边界就是000,005,010……995。

hbase> create 't1', 'f1', SPLITS => ['10', '20', '30', '40']  

hbase> create 't1', 'f1', SPLITS_FILE => 'splits.txt'

hbase> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
private void createTable() {
   HBaseAdmin admin = null; String tableName="NewTable";            
   String columnFamilyName="cf";
   try {
    Configuration conf = HBaseConfiguration.create();
    admin = new HBaseAdmin(conf);
    TableName tableNameV = TableName.valueOf(tableName);
    if (admin.tableExists(tableNameV)) {    
     System.out.println("Table " + tableName + " already  
     exist."
);
     return;
        }
  HTableDescriptor tableDesc = new
  HTableDescriptor(tableNameV);
  HColumnDescriptor columnDesc = new  
  HColumnDescriptor(columnFamilyName);  
  tableDesc.addFamily(columnDesc);
  admin.createTable(tableDesc, splits());  
 System.out.println("Created table : " + tableName + "  
  successfully."
);
 } catch (Exception e) {
  System.out.println("Failed create table " + tableName+ e.toString());
  }
}
private static byte splits() {}



HBase优化之预分区

长按下面的二维码加入HBase技术社区微信群

以上是关于HBase优化之预分区的主要内容,如果未能解决你的问题,请参考以下文章

Hbase­优化方案

HBase性能优化方法总结

HBase设计与开发性能优化

HBase工作中的一些优化方法

HBase性能优化方法总结

HBase性能优化一——表的设计