1 写入阻塞
表现为服务器数据无法写入,RegionServer经常宕机,修复方法优先级从高到低:
1.1 RegionServer堆内存设置太小
默认1GB,Memstore占40%,非常容易阻塞
1.2 HFile达到了最大的数量阀值
如果HFile达到了hbase.hstore.blockingStoreFiles最大数量,Memstore就不能继续刷写数据到HDFS,而数据还会继续加入Memstore,导致Memstore阻塞。所以可以适当调大该阀值
1.3 Memstore的大小达到阀值
当Memstore达到了hbase.hregion.memstore.flush.size * hbase.hregion.memstore.block.multiplier时候,就无法写入到Memstore了,这是后就直接表现为写入阻塞。可以略微调大这两个参数,单实际作用不大。
1.4 整个RegionServer上的Memstore总内存达到了一个阀值
当整个RegionServer上的Memstore总内存占用到达到了hbase.regionserver.global.memstore.size,就会导致写入阻塞,也就是占用堆内存的比例,默认0.4,虽然可以调大,但是Memstore+BlockCache的总内存不能超过80%,否则会报错,所以尽量不要设置这个参数。
2 朱丽叶暂停
集群运行了一段时间,导致RegionServer莫名其妙的宕机了,重启虽然可以解决暂时,但是无法避免,具体情况原因有一下几点:
- Zookeeper检测到一个RegionServer太久没有心跳回应,会表机其为死亡
- FullGC导致REgionServer发生了STW,依旧被Zookeeper标记为了死亡
- 如果RegionServer标记为了死亡,其他RegionServer会分担其上的所有数据,执行一些列的恢复步骤
- 这个RegionServer虽然之后活过来了,但是发现已经被标记为死亡,只能自杀来防止整个集群乱套了
2.1 RegionServer堆内存设置太小
还是那个问题,默认1G,很容易发生性能问题
2.2 Zookeeper的心跳超时时间太小
默认超时时间是90s,但是因为HBase的机制原因,实际只有40s的超时时间,设置方法具体如下:
首先在hbase-site.xml中增加zookeeper超时配置项:
<property>
<name>zookeeper.session.timeout</name>
<value>18000</value>
</property>
但是Zookeeper自己还有一个超时时间:
#conf/zoo.cfg中的tickTime,默认为2s
tiackTime=2000
#通过tickTime计算出minSessionTimeout
minSessionTimeout = 2* tickTime =4s
#通过tickTime计算出maxSessionTimeout
maxSessionTimeout =20 * tickTime =40s
#如果zookeeper.session.timeout < minSessionTimeout,那么最终采用minSessionTimeout。
#如果zookeeper.session.timeout > maxSessionTimeout,那么最终采用maxSessionTimeout。
所以随人上边配置了180s,但是实际还是使用40S作为超时时间,所以还需要调大tickTime,这个方案不建议在生产环境上使用,生产环境要保证sessionTimeout越小越好,越小表示集群对宕机的响应时间越短,服务的稳定性越高。
2.3 选择合适的GC回收策略
FullGC导致的朱丽叶暂停可以根据堆内存大小来选择合适的GC策略
- 堆内存小于4G,使用-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
- 堆内存大于4G小于32G,使用-XX:+UserParNewGC -XX:+UserConcMarkSweepGC或者-XX:UseG1GC
- 堆内存大于32G,使用-XX:UseG1GC
2.4 使用新的内存空间策略
使用HBase专用的MSLAB内存空间策略,把内存空间分为很多歌独立的Chunk,消除了堆内存的碎片问题,几乎消除了FullGC,同时配合G1GC效果更好,默认MSLAB为开启,但是没分配chunck相当于关闭,开启方式为:
hbase.hregion.memstore.mslab.enabled=true
#整个Memstore可以占用的内存存中Memstore的比例,设置为非0.0即为开启,0.0-1.0
hbase.hregion.memstore.chunkpoll.maxsize
#预分配chunk占总的chunkPool的比例,是一个百分比,取值范围是0.0-1.0,预分配一些性能会更加平滑
hbase.hregion.memstore.chunkpool.initialsize
3 读取性能调优
如果应用的性能读大于写,那么应该做适量的读取调优,可以从API和系统配置两方面来进行配置。遇到读写性能瓶颈的时候,要优先考虑API是不是使用合理,比如对Scan的内部工作原理不熟悉导致写出的Scan额外遍历了非常多不需要遍历的KeyValue。
3.1 使用过滤器
学习并了解各种过滤器的原理,灵活的在业务上使用合适的过滤器可以减少不必要的遍历次数,比如前缀过滤器、分页过滤器。
3.2 增加BlockCache
虽然增加BlockCache的容量可以有更多数据被缓存,但是最终是否有效,还是由命中率决定的,如果命中率本身就很高,那么增加BlockCache的性能应该可以提升很明显,而命中率低的话可以考虑增加命中率。命中率的查看的获取步骤为:
- 访问RegionServer的指标页面,16030端口,老版本为60030
- 查找Hadoop:service=HBase,name=RegionServer,sub=Server指标区域
- 分别找到blockCacheCountHitPercent和blockCacheExpressHitPercent。
增加BlockCache要注意的是,BlockCache+Memstore的总内存比例不能超过RegionServer堆内存的0.8,两者默认都是0.4,所以必须要适当调小Memstore。
3.3 修改HFile合并策略
调整Compaction策略,让HFile的数量尽量减少,以减少每次Scan的跨HFile的次数,但是同时又要保证该合并策略适用于任务场景,并且compaction次数不能太频繁。