记一次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
1245 0
|
云安全 Java Shell
EMR主节点内存异常100%,hbase服务异常
EMR主节点内存异常100%,hbase服务异常
|
存储 SQL 缓存
图文详解:内存总是不够,我靠HBase说服了Leader为新项目保驾护航
大家好,我是小羽最近在工作中用到了 Hbase 这个数据库,也顺便做了关于 Hbase 的知识记录来分享给大家。其实 Hbase的内容体系真的很多很多,这里介绍的是小羽认为在工作中会用到...
289 0
|
分布式数据库 Hbase
|
缓存 Java 分布式数据库
排查HBase内存泄漏导致RegionServer挂掉问题
问题描述 在测试Phoenix稳定性时,发现HBase集群其中一台RegionServer节点FullGC严重,隔一段时间就会挂掉。 HBase集群规格       初步分析 使用jstat监控RegionServer的Heap Size和垃圾回收情况 Old区内存一直在90%多,且FullGC次数一直在增多。
2356 0
|
监控 Java 分布式数据库
|
算法 大数据 分布式数据库
storm自定义分组与Hbase预分区结合节省内存消耗
Hbas预分区   在系统中向hbase中插入数据时,常常通过设置region的预分区来防止大数据量插入的热点问题,提高数据插入的效率,同时可以减少当数据猛增时由于Region split带来的资源消耗。
1294 0
|
分布式数据库 Hbase
zookeeper的maxSessionTimeout默认值导致hbase regionserver超时
zookeeper的maxSessionTimeout默认值导致hbase regionserver超时 在hbase中经常会遇到regionserver挂掉的情况,查看日志会看到这样的错误信息 2016-02-16 11:51:24,882 WARN  [master/hadoop02/192.
3090 0
|
7月前
|
分布式计算 Ubuntu Hadoop
Ubuntu22.04下搭建Hadoop3.3.6+Hbase2.5.6+Phoenix5.1.3开发环境的指南
呈上,这些步骤如诗如画,但有效且动人。仿佛一个画家在画布上描绘出一幅完美的画面,这就是你的开发环境。接下来,尽情去创造吧,祝编程愉快!
506 19
|
分布式计算 Java Hadoop
java使用hbase、hadoop报错举例
java使用hbase、hadoop报错举例
335 4