每隔一段时间,hbase 的读就会停顿10s的原因及解决办法

产生的原因:前段时间由于设置region server 的heapsize 为16g,使得block cache 的大小变为16g*0.4=3.2g,查看日志发现了jvm 隔一段时间会出现如下日志:

2015-03-24 16:09:27,405 WARN org.apache.hadoop.hbase.util.JvmPauseMonitor: Detected pause in JVM or host machine (eg GC): pause of approximately 15959msGC pool ‘ParNew’ had collection(s): count=1 time=213msGC pool ‘ConcurrentMarkSweep’ had collection(s): count=1 time=16158ms:28:42,048 WARN org.apache.hadoop.hbase.util.JvmPauseMonitor: Detected pause in JVM or host machine (eg GC): pause of approximately 20125msGC pool ‘ParNew’ had collection(s): count=1 time=337msGC pool ‘ConcurrentMarkSweep’ had collection(s): count=2 time=20206ms

由此可以断定block cache 发生了CMS GC,长达10s,甚至20s,

目前使用的BlockCache,使用一个HashMap维护Block Key到Block的映射,采用严格的LRU算法来淘汰Block,初始化时会指定容量大小,当使用量达到85%的时候开始淘汰block至75%的比例。 优点:直接采用jvm提供的HashMap来管理Cache,简单可依赖;内存用多少占多少,JVM会帮你回收淘汰的BlOCK占用的内存 缺点: 1.一个Block从被缓存至被淘汰,基本就伴随着Heap中的位置从New区晋升到Old区 2.晋升在Old区的Block被淘汰后,最终由CMS进行垃圾回收,随之带来的是Heap碎片 ,old 区域变大导致cms 时间过长。 3.因为碎片问题,随之而来的是GC时晋升失败的FullGC,,我们的线上系统根据不同的业务特点,因为这个而发生FullGC的频率,有1天的,1周的,1月半年的都有。对于高频率的, 在运维上可以通过在半夜手工触发FullGC来缓解 4.如果缓存的速度比淘汰的速度快,很不幸,现在的代码有OOM的风险(这个可以修改下代码避免)

解决方案: hbase-0.94以后提供了BucketCache, 一方面降低region server heap size 的大小为8gb,降低cms发生的几率和减少时间,另一方面可以利用BucketCache增加二级缓存。二级缓可以利用off heap cache,也可也利用ssd 做二级缓存。 CDH5.3.0 的配置如下:在region server 上添加 XX:MaxDirectMemorySize=16G

在region server hbase-site 配置BucketCache size:

>offheap> >>16384</value></property>

由于增加了读缓存:已缓存的块增加了一倍,总的命中率增加了60%多

参考文档:

人生就像爬坡,要一步一步来。

每隔一段时间,hbase 的读就会停顿10s的原因及解决办法

相关文章:

你感兴趣的文章:

标签云: