记一次HBase内存泄漏导致RegionServer挂掉问题

简介:

问题描述

在测试Phoenix稳定性时,发现HBase集群其中一台RegionServer节点FullGC严重,隔一段时间就会挂掉。

HBase集群规格

选项 Master RegionServer
节点数 2台,一主一备 3台
CPU核数 2core 4core
存储 SSD云盘,单节点440G

初步分析

使用jstat监控RegionServer的Heap size和垃圾回收情况:

[root@iZbp18zqovyu9djsjb05dzZ ~]# jstat -gcutil 454 5000
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
100.00   0.00  55.68  90.19  98.75  97.30   2244   57.381    149    3.411   360.792
100.00   0.00  55.84  91.32  98.75  97.30   2244   57.381    150    4.724   365.516
100.00   0.00  56.30  92.22  98.75  97.30   2244   57.381    150    4.724   365.516
100.00   0.00  56.88  91.55  98.75  97.30   2244   57.381    151    3.411   368.927
100.00   0.00  57.09  92.37  98.75  97.30   2244   57.381    152    4.057   372.984

OLD区内存一直在90%多,且FullGC次数一直在增多。

通过ganglia查看集群的FullGC情况,也可以看出003节点持续在FullGC,并最终挂掉。
image

怀疑存在内存泄漏导致FullGC可回收的内存越来越小,回收的时间也越来越长,最终导致RegionServer心跳超时,被Master干掉。

问题定位

排查内存泄漏问题,可借助jmap分析java堆内存的占用情况

使用jmap将RegionServer堆内存dump下来:

[root@iZbp16ku9i9clejitib6dzZ opt]# jmap -dump:format=b,file=regionserver.bin 30590
Dumping heap to /opt/regionserver.bin ...
Heap dump file created

然后借助MAT内存分析工具分析RegionServer的堆内存占用情况:
image

MAT提供了Memory Leak Suspect Report分析功能,可帮助我们找到可能存在泄漏的对象:
image
可以看到Configuration对象已经占用到80%堆内存,Configuration底层使用HashTable存配置的键值对,与上图内存分配相符,但是还不确定这么多对象是哪里来的以及为什么没有被回收。

查看内存泄漏详细信息:
image
看到这有点懵,Configuration与FSHLog有啥关系呢,这时就要结合Configuration的引用链和HBase的源码来看了。
在堆内存Histogram中,过滤到Configuration对象,然后Merge Shortest path to GC Roots:
image
观察到GCRoot最多的就是FSHLog,查看引用链:
image
FSHLOG引用了OpenRegionHandler$PostOpenDeployTasksThread线程对象,进一步引用了HRegion,HRegion引用了Coprocessor,然后引用Configuration对象,导致内存泄露。

结合FSHLog源码

 /**
   * Map of {@link SyncFuture}s keyed by Handler objects.  Used so we reuse SyncFutures.
   * TODO: Reus FSWALEntry's rather than create them anew each time as we do SyncFutures here.
   * TODO: Add a FSWalEntry and SyncFuture as thread locals on handlers rather than have them
   * get them from this Map?
   */
  private final Map<Thread, SyncFuture> syncFuturesByHandler;

  ...

  private SyncFuture getSyncFuture(final long sequence, Span span) {
   
    SyncFuture syncFuture = this.syncFuturesByHandler.get(Thread.currentThread());
    if (syncFuture == null) {
   
      syncFuture = new SyncFuture();
      this.syncFuturesByHandler.put(Thread.currentThread(), syncFuture);
    }
    return syncFuture.reset(sequence, span);
  }

syncFuturesByHandler缓存了写WAL的每个线程,但是在线程结束时并不会清除Map中缓存的线程,导致引用的Configuration对象不会被释放。

问题修复

目前该问题已有阿里云HBase社区commiter正研修复,并贡献给社区:https://issues.apache.org/jira/browse/HBASE-21228

目录
相关文章
|
存储 缓存 固态存储
HBase 性能调优第一弹:内存篇
这是使用 HBase 最不可避免的一个话题,就是 HBase 的性能调优,而且通常建立在我们对 HBase 内部运行机制比较了解的基础上进行的,因此无论怎么说,调优这块都是一个相对复杂的事情。这一篇我们先来介绍与 HBase 内存最相关的调优内容。 1. 合理配置 JVM 内存 这里首先涉及 HBase 服务的堆内存设置。一般刚部署的 HBase 集群,默认配置只给 Master 和 RegionServer 分配了 1G 的内存,RegionServer 中 MemStore 默认占 0.4 即 400MB 左右的空间,而一个 MemStore 刷写阈值默认 128M,所以一个 Regi
1435 0
|
云安全 Java Shell
EMR主节点内存异常100%,hbase服务异常
EMR主节点内存异常100%,hbase服务异常
|
存储 SQL 缓存
图文详解:内存总是不够,我靠HBase说服了Leader为新项目保驾护航
大家好,我是小羽最近在工作中用到了 Hbase 这个数据库,也顺便做了关于 Hbase 的知识记录来分享给大家。其实 Hbase的内容体系真的很多很多,这里介绍的是小羽认为在工作中会用到...
341 0
|
分布式数据库 Hbase
|
缓存 Java 分布式数据库
排查HBase内存泄漏导致RegionServer挂掉问题
问题描述 在测试Phoenix稳定性时,发现HBase集群其中一台RegionServer节点FullGC严重,隔一段时间就会挂掉。 HBase集群规格       初步分析 使用jstat监控RegionServer的Heap Size和垃圾回收情况 Old区内存一直在90%多,且FullGC次数一直在增多。
2485 0
|
监控 Java 分布式数据库
|
算法 大数据 分布式数据库
storm自定义分组与Hbase预分区结合节省内存消耗
Hbas预分区   在系统中向hbase中插入数据时,常常通过设置region的预分区来防止大数据量插入的热点问题,提高数据插入的效率,同时可以减少当数据猛增时由于Region split带来的资源消耗。
1355 0
|
分布式数据库 Hbase
zookeeper的maxSessionTimeout默认值导致hbase regionserver超时
zookeeper的maxSessionTimeout默认值导致hbase regionserver超时 在hbase中经常会遇到regionserver挂掉的情况,查看日志会看到这样的错误信息 2016-02-16 11:51:24,882 WARN  [master/hadoop02/192.
3186 0
|
10月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
3169 0
|
10月前
|
存储 缓存 NoSQL
内存管理基础:数据结构的存储方式
数据结构在内存中的存储方式主要包括连续存储、链式存储、索引存储和散列存储。连续存储如数组,数据元素按顺序连续存放,访问速度快但扩展性差;链式存储如链表,通过指针连接分散的节点,便于插入删除但访问效率低;索引存储通过索引表提高查找效率,常用于数据库系统;散列存储如哈希表,通过哈希函数实现快速存取,但需处理冲突。不同场景下应根据访问模式、数据规模和操作频率选择合适的存储结构,甚至结合多种方式以达到最优性能。掌握这些存储机制是构建高效程序和理解高级数据结构的基础。
1040 1