HBase-线上问题排查思路

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次数不能太频繁。

4 其他紧急检查命令

    原文作者:蠟筆小噺没有烦恼
    原文地址: https://www.jianshu.com/p/5687ac3bd1d4
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞