HBase实战 | 排查HBase堆外内存溢出

一.溢出现象

单台服务器刚发布时 java 进程占用3g,以一天5%左右的速度增长,一定时间过后进程占用接近90%,触发服务器报警,而此时 Old 区占用在 50%,未触发 CMS GC,而导致堆外内存溢出。

异常堆栈:

top 命令查看进程占用:

机器为 8核16G,JVM配置如下:

-Xms8g -Xmx8g -Xmn3g -Xss512k 
-XX:MetaspaceSize=256m 
-XX:MaxMetaspaceSize=512m 
-XX:+UseConcMarkSweepGC 
-XX:+DisableExplicitGC 
-XX:-UseGCOverheadLimit
-XX:+UseCMSInitiatingOccupancyOnly 
-XX:CMSInitiatingOccupancyFraction=70
-XX:+CMSParallelRemarkEnabled 
-XX:+UseFastAccessorMethods 

大数据是未来的发展方向,正在挑战我们的分析能力及对世界的认知方式,因此,我们与时俱进,迎接变化,并不断的成长!大数据学习群:957205962 一起讨论进步学习

二.排查过程&原理分析

1.初步分析

根据异常堆栈,可以看出是 hbase.write() 分配直接内存导致的堆外内存溢出。而直接内存分配空间不足时,会调用 System.gc(),由于 JVM 参数配置了 -XX:+DisableExplicitGC 禁用了 System.gc(),且 Old 区占用才50%,未达到 CMS GC 阈值,因此抛出堆外内存溢出。

粗略的堆外内存计算方式:

JVM 未设置直接内存大小参数 -XX:MaxDirectMemorySize, 则 CMS GC堆外内存为:Old 区 - 1个 Survivor 区, 即 8G - 314M = 7.8G。

 

2.压测主要接口

因为不能用线上机器做实验,且不能确定是否有其他因素导致溢出。于是在性能环境使用 Jmeter 压测应用主要接口,并观察堆外内存占用。

压测后发现堆外内存占用平稳,未出现溢出现象。

 

3.释放 HBase Client 资源

此时将目光放到异常堆栈上,并查看系统封装的 hbase client ,发现使用完 HTable 后未调用 close() 释放资源,于是加上 close() 代码,并上线观察。但仍然出现溢出现象。

 

4.压测特定功能

虽然不是 HBase Client 使用的问题,但还是有相同的堆栈,说明 HBase 肯定有问题。

查找资料,发现 HBase 官方的 issue 列表里有一个堆外内存溢出的 case (hbase direct memory leak issue)。发

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值