解决NodeManager跑半年左右就频繁触发FULL-GC的内存泄露问题_nodemanager gc-程序员宅基地

技术标签: 大数据  

解决NodeManager跑半年左右就频繁触发FULL-GC的内存泄露问题

故障过程

我们的集群用的事2.7.3版本的集群,NodeManager跑半年左右就会频繁触发FULL-GC,然后重启。然后发现这是一个普遍现象,集群里的机器好像都是这个节奏,过了半年之后,就会触发FULL-GC告警,然后重启一下。

到底是为什么呢,我们带着这个问题,开始进行排查工作。我们找到一台触发FULL-GC的机器,DUMP内存快照。然后通过我们蘑菇街内部的内存快照分析工具进行分析
看了一下排除可回收对象之后,不可回收内存大约2.5G
在这里插入图片描述
根据引用链分析,内存消耗主要集中再俩块,一块是org.apache.hadoop.hdfs.DistributedFileSystem 相关的引用链路上,一块是java.lang.ThreadLocal$ThreadLocalMap 相关的引用链路上
在这里插入图片描述

我们先看看DistributedFileSystem 相关的信息,到GC_ROOT引用链
在这里插入图片描述
子属性列表
在这里插入图片描述
上面就是DistributedFileSystem 引用链路的相关情况,那么另外一块占用内存比较多的ThreadLocalMap是什么呢?我们也翻了翻源码。

@InterfaceAudience.LimitedPrivate({
     "MapReduce", "HBase" })
@InterfaceStability.Unstable
public class DistributedFileSystem extends FileSystem {
    
  private Path workingDir;
  private URI uri;
  private String homeDirPrefix =
      DFSConfigKeys.DFS_USER_HOME_DIR_PREFIX_DEFAULT;

DistributedFileSystem是继承与 FileSystem的
然后看下 FileSystem 的源码

@InterfaceAudience.Public
@InterfaceStability.Stable
public abstract class FileSystem extends Configured implements Closeable {
    
  public static final String FS_DEFAULT_NAME_KEY = 
                   CommonConfigurationKeys.FS_DEFAULT_NAME_KEY;
  public static final String DEFAULT_FS = 
                   CommonConfigurationKeys.FS_DEFAULT_NAME_DEFAULT;
                   
.......(这里略过N行)

private final String scheme;

    /**
     * rootData is data that doesn't belong to any thread, but will be added
     * to the totals.  This is useful for making copies of Statistics objects,
     * and for storing data that pertains to threads that have been garbage
     * collected.  Protected by the Statistics lock.
     */
    private final StatisticsData rootData;

    /**
     * Thread-local data.
     */
    private final ThreadLocal<StatisticsData> threadData;

好了找到这个 ThreadLocal了, 那么他们为什么不在一个引用链上呢?看过ThreadLocal 源码的同学应该都知道,ThreadLocal 就是一个工具类,他本身不存放任何对象,真正的对象都存放在Thread下面的ThreadLocalMap中,所以他们并不在一个引用链上。

根据以上分析大致确定是 DistributedFileSystem 对象过多导致的内存泄露问题, 为了确认这个问题,我们找了一个重启过后跑了一断时间的机器,做对比
在这里插入图片描述
只有41个对象, 比之前的2700多个 要少了很多。
然后我们就考虑到底为什么内存泄露,而且这个内存泄露有点奇葩,如果真的有严重的泄露问题,理论上最多几天之后就会FULL-GC然后OOM,但是他确能抗这么久,然后才会出现情况。
基于上诉问题,感觉应该是HSF客户端没正确关闭,或 没正确释放,导致没被回收,并且只有极少数极端情况下才会发生这个问题,带着个疑问,我们翻了翻源码,重点关注关闭时的情况
我们翻阅了DFSClient源码,看到了2个方法,其中一个是close

/**
   * Closes this output stream and releases any system 
   * resources associated with this stream.
   */
  @Override
  public void close() throws IOException {
    
    synchronized (this) {
    
      TraceScope scope = dfsClient.getPathTraceScope("DFSOutputStream#close",
          src);
      try {
    
        closeImpl();
      } finally {
    
        scope.close();
      }
    }
    dfsClient.endFileLease(fileId);
  }

这个方法如果在执行closeImpl异常时,dfsClient.endFileLease(fileId); 将不会被执行到

另外一个

/**
   * Aborts this output stream and releases any system 
   * resources associated with this stream.
   */
  void abort() throws IOException {
    
    synchronized (this) {
    
      if (isClosed()) {
    
        return;
      }
      streamer.setLastException(new IOException("Lease timeout of "
          + (dfsClient.getHdfsTimeout() / 1000) + " seconds expired."));
      closeThreads(true);
    }
    dfsClient.endFileLease(fileId);
  }

这里如果closeThreads发生异常,dfsClient.endFileLease(fileId);也将不会被执行到,
如果dfsClient.endFileLease(fileId)不被执行到,那么会导致文件没有释放,也就产生了Client泄露,基于这个问题,我们查了一下官方,发现已经有了这个patch了:https://issues.apache.org/jira/browse/HDFS-10549
好了此问题终结!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43990680/article/details/104754341

智能推荐

linux gcc-c++等依赖安装以及防火墙基础命令_gcc-c++安装包-程序员宅基地

文章浏览阅读3.5k次,点赞2次,收藏7次。linux gcc-c++等依赖安装以及防火墙基础命令_gcc-c++安装包

sybase安装字符集_sybase12.5添加字符集-程序员宅基地

文章浏览阅读1.6k次。我是在windows环境下安装了一个sybase数据库。1、找到要安装的字符集目录D:\ProgramFiles\sybase12.5\charsets\cp850 ,这个目录是在sybaes的安装目录;sybae默认不会安装所有的字符集,如果你需要的字符集数据库没有安装的话;可以自行进行安装。在cp850同级目录还有许多的其他字符集。2_sybase12.5添加字符集

一文了解路由平台的 Cisco IOS 和 IOS XE 命名约定,看这篇就够了_ios xe system 在哪些设备-程序员宅基地

文章浏览阅读4.9k次。文章目录概述命名约定一致性IOSCisco IOS XE 软件版本 16 和 17IOS XE 软件版本 3SIOS XE Train 标识符物理平台虚拟平台IOS经典Cisco IOS 软件版本 15IOS 经典列车标识符物理平台概述命名约定一致性对某事物进行任何命名约定的全部意义在于使事物保持一致和统一。遵守约定可为专业人员提供基本规则,让他们坚持已知的内容,为现在和未来的员工以及使用思科产品的人员提供清晰简洁的信息。本文概述了Cisco 路由平台的 Cisco IOS 命名约定,包括 IOS _ios xe system 在哪些设备

Nginx反向代理L4后进行keepalived检测_l4的代理-程序员宅基地

文章浏览阅读442次。1、10和11上安装nginx代理12和13和keepalived并配置yum install nginx keepalived -yvim /etc/nginx/nginx.conf末尾添加stream { upstream kube-apiserver { server 10.4.7.12:6443 max_fails=3 fail_timeout=30..._l4的代理

Java后台获取小程序用户信息和登录_java 小程序 后端获得userinfo 2024-程序员宅基地

文章浏览阅读2.1k次。登录请求体public class MiniProgramLoginCommand { private String jsCode; private String encryptedData; private String iv;}核心代码private static final Logger logger = LoggerFactory.getLogger(XX..._java 小程序 后端获得userinfo 2024

HDFS(12)--HDFS的javaAPI操作_java hdfs api filesystem exists-程序员宅基地

文章浏览阅读1.9k次。创建maven工程并导入jar包<repositories><repository><id>cloudera</id><url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>&..._java hdfs api filesystem exists

随便推点

【转载】WPF自定义控件与样式(1)-矢量字体图标(iconfont)_/k.framework.controls;component/resources/#sf2015-程序员宅基地

文章浏览阅读1.4k次。原文地址:http://www.cnblogs.com/anding/p/4961215.html一.图标字体  图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap。但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般外置字体一样的使用,因此Winform、WPF中都是可以用的。  在我们多个_/k.framework.controls;component/resources/#sf2015

k8s gcr.io/google-samples/hello-frontend:1.0 镜像无法下载_docker pull gcr.io/google-samples/node-hello:1.0-程序员宅基地

文章浏览阅读2.5k次。Failed to pull image "gcr.io/google-samples/hello-frontend:1.0": rpc error: code = Unknown desc = Error response from daemon: Get https://gcr.io/v2/: net/http: request canceled while waiting for conne..._docker pull gcr.io/google-samples/node-hello:1.0

vector数组的初始化_vector数组初始化-程序员宅基地

文章浏览阅读2.2k次。1.已知元素的初始化vector a={1,2,3,4,5};2.需要输入元素的初始化(1)先将vector中所有元素初始化为0vector a(n)或vector a(n,0)#include<iostream>#include<vector>using namespace std;int main(){ int n; cin >&..._vector数组初始化

二级c语言105道上机题库,微机原理及应用习题105道-程序员宅基地

文章浏览阅读5.3k次。《微机原理与应用》习题1. 求ADDRI开始单元中连续存放的两个双字数据之和,将结果存放在ADDR2开始的单元,并将结果在显示器上显示出来。(假定和不超过双字) 2. 在一个首地址为STR、长度为N的字符串中查找“空格”,找到则向DL中送1,否则向DL中送-1。 3. 将两位十六进制数转换成ASCII码,并送屏幕显示,要求使用顺序结构实现。 4. 使用分支结构实现将1位十六进制数转换成ASCII码..._自1000h单元开始有1000个单字节带符号数

python fabric2.X版本-程序员宅基地

文章浏览阅读998次。2019独角兽企业重金招聘Python工程师标准>>> ..._python通过fabric2可以用rsync吗

DAO设计模式_dao设计模式最广泛-程序员宅基地

文章浏览阅读278次。DAO (Data Access Object,数据访问对象)的主要功能是数据操作,提供多个原子性的DAO操作,如增加、修改、删除等,都于原子性的操作。DAO主要由以下几个部分组成:1.DatabaseConnection:专门负责数据库的打开与关闭操作的类。2.VO:主要由属性、setter、getter方法组成3.DAO:主要定义操作的接口,定义一系列数据库的原子性操_dao设计模式最广泛