HBase 性能优化笔记

1 hbase.hregion.max.filesize应该设置多少合适html

2 autoflush=false的影响数据库

3 从性能的角度谈table中family和qualifier的设置缓存

4 hbase.regionserver.handler.count详解网络

1 hbase.hregion.max.filesize应该设置多少合适
默认值:256M
说明:Maximum HStoreFile size. If any one of a column families' HStoreFiles has grown to exceed this value, the hosting HRegion is split in two.性能

HStoreFile的最大值。若是任何一个Column Family(或者说HStore)的HStoreFiles的大小超过这个值,那么,其所属的HRegion就会Split成两个。测试

调优this

hbase中hfile的默认最大值(hbase.hregion.max.filesize)是256MB,而google的bigtable论文中对tablet的最大值也推荐为100-200MB,这个大小有什么秘密呢?
  众所周知hbase中数据一开始会写入memstore,当memstore满64MB之后,会flush到disk上而成为storefile。当storefile数量超过3时,会启动compaction过程将它们合并为一个storefile。这个过程当中会删除一些timestamp过时的数据,好比update的数据。而当合并后的storefile大小大于hfile默认最大值时,会触发split动做,将它切分红两个region。
  lz进行了持续insert压力测试,并设置了不一样的hbase.hregion.max.filesize,根据结果获得以下结论:值越小,平均吞吐量越大,但吞吐量越不稳定;值越大,平均吞吐量越小,吞吐量不稳定的时间相对更小。google

  为何会这样呢?推论以下:线程

    a 当hbase.hregion.max.filesize比较小时,触发split的机率更大,而split的时候会将region offline,所以在split结束的时间前,访问该region的请求将被block住,客户端自我block的时间默认为1s。当大量的region同时发生split时,系统的总体访问服务将大受影响。所以容易出现吞吐量及响应时间的不稳定现象
    b 当hbase.hregion.max.filesize比较大时,单个region中触发split的机率较小,大量region同时触发split的机率也较小,所以吞吐量较之小hfile尺寸更加稳定些。可是因为长期得不到split,所以同一个region内发生屡次compaction的机会增长了。compaction的原理是将原有数据读一遍并重写一遍到hdfs上,而后再删除原有数据。无疑这种行为会下降以io为瓶颈的系统的速度,所以平均吞吐量会受到一些影响而降低。
    综合以上两种状况,hbase.hregion.max.filesize不宜过大或太小,256MB或许是一个更理想的经验参数。对于离线型的应用,调整为128MB会更加合适一些,而在线应用除非对split机制进行改造,不然不该该低于256MBserver

2 autoflush=false的影响

  不管是官方仍是不少blog都提倡为了提升hbase的写入速度而在应用代码中设置autoflush=false,而后lz认为在在线应用中应该谨慎进行该设置。缘由以下:

  a autoflush=false的原理是当客户端提交delete或put请求时,将该请求在客户端缓存,直到数据超过2M(hbase.client.write.buffer决定)或用户执行了hbase.flushcommits()时才向regionserver提交请求。所以即便htable.put()执行返回成功,也并不是说明请求真的成功了。假如还没有达到该缓存而client崩溃,该部分数据将因为未发送到regionserver而丢失。这对于零容忍的在线服务是不可接受的。

  b autoflush=true虽然会让写入速度降低2-3倍,可是对于不少在线应用来讲这都是必须打开的,也正是hbase为何让它默认值为true的缘由。当该值为true时,每次请求都会发往regionserver,而regionserver接收到请求后第一件事就是写hlog,所以对io的要求是很是高的,为了提升hbase的写入速度,应该尽量高地提升io吞吐量,好比增长磁盘、使用raid卡、减小replication因子数等

3 从性能的角度谈table中family和qualifier的设置
  对于传统关系型数据库中的一张table,在业务转换到hbase上建模时,从性能的角度应该如何设置family和qualifier呢?
  最极端的,①每一列都设置成一个family,②一个表仅有一个family,全部列都是其中的一个qualifier,那么有什么区别呢?

  从读的方面考虑:
  family越多,那么获取每个cell数据的优点越明显,由于io和网络都减小了。

  若是只有一个family,那么每一次读都会读取当前rowkey的全部数据,网络和io上会有一些损失。

  固然若是要获取的是固定的几列数据,那么把这几列写到一个family中比分别设置family要更好,由于只需一次请求就能拿回全部数据。

  从写的角度考虑:

  首先,内存方面来讲,对于一个Region,会为每个表的每个Family分配一个Store,而每个Store,都会分配一个MemStore,因此更多的family会消耗更多的内存。
  其次,从flush和compaction方面说,目前版本的hbase,在flush和compaction都是以region为单位的,也就是说当一个family达到flush条件时,该region的全部family所属的memstore都会flush一次,即便memstore中只有不多的数据也会触发flush而生成小文件。这样就增长了compaction发生的机率而compaction也是以region为单位的,这样就很容易发生compaction风暴从而下降系统的总体吞吐量
  第三,从split方面考虑,因为hfile是以family为单位的,所以对于多个family来讲,数据被分散到了更多的hfile中,减少了split发生的机率。这是把双刃剑。更少的split会致使该region的体积比较大,因为balance是以region的数目而不是大小为单位来进行的,所以可能会致使balance失效。而从好的方面来讲,更少的split会让系统提供更加稳定的在线服务。而坏处咱们能够经过在请求的低谷时间进行人工的split和balance来避免掉。
     所以对于写比较多的系统,若是是离线应该,咱们尽可能只用一个family好了,但若是是在线应用,那仍是应该根据应用的状况合理地分配family

4 hbase.regionserver.handler.count

 RegionServer端开启的RPC监听器实例个数,也即RegionServer可以处理的IO请求线程数。默认是10.

 此参数与内存息息相关。该值设置的时候,以监控内存为主要参考。

 对于 单次请求内存消耗较高的Big PUT场景(大容量单次PUT或设置了较大cache的scan,均属于Big PUT)或ReigonServer的内存比较紧张的场景,能够设置的相对较小。

 对于 单次请求内存消耗低,TPS(TransactionPerSecond,每秒事务处理量)要求很是高的场景,能够设置的相对大些。

相关文章
相关标签/搜索