ES内存持续增长问题分析

环境介绍

es版本:5.6.4
-Xms31g -Xmx31g
-XX:MaxDirectMemorySize=10g

问题说明

用top命令观察ES使用的物理内存不断增加到54.6G
在这里插入图片描述
已知堆内存31G,堆外内存MaxDirectMemorySize 10G,那么内存使用最高应该不超过41G才对。现在内存使用了54.6G明显超过了预估,那么除了已知的41G外,还有哪些我们不知道的地方在占用内存呢?

问题分析

为了弄清楚54.6g内存有哪些部分组成,我打开了内存映射文件 /proc/ES进程号/smaps

在这里插入图片描述
首先我们截取文件中的一段来介绍怎么看这个文件:

  • 7e1cde88b000-7e1ce4acf000 是该虚拟内存段的开始和结束位置
  • r–s内存段的权限,最后一位p代表私有,s代表共享
  • 00000000 该虚拟内存段在对应的映射文件中的偏移量
  • 08:20 文件的主设备和次设备号
  • 21365069 被映射到虚拟内存的文件的索引节点号
  • /mnt/ssd1/data/cluster001/SERVICE-ELASTICSEARCH-retro/nodes/0/indices/iB4FRrDrQNSxIp8-VAegbw/3/index/_841x.cfs
    被映射到虚拟内存的文件名称。后面带(deleted)的是内存数据,可以被销毁。
  • size 是进程使用内存空间,并不一定实际分配了内存(VSS)
  • Rss是实际分配的内存(不需要缺页中断就可以使用的)
  • Pss是平摊计算后的使用内存(有些内存会和其他进程共享,例如mmap进来的)
  • Shared_Clean 和其他进程共享的未改写页面
  • Shared_Dirty 和其他进程共享的已改写页面
  • Private_Clean 未改写的私有页面页面
  • Private_Dirty 已改写的私有页面页面
  • Referenced 标记为访问和使用的内存大小
  • Anonymous 不来自于文件的内存大小
  • Swap 存在于交换分区的数据大小(如果物理内存有限,可能存在一部分在主存一部分在交换分区)
  • KernelPageSize 内核页大小
  • MMUPageSize MMU页大小,基本和Kernel页大小相同

由介绍可以知道top命令中的RES表示进程实际占有的内存大小,它通过把smaps文件中所有的Rss累计得到的。可以通过以下命令计算:

grep Rss smaps |awk 'BEGIN {sum = 0;} {sum += $2} END{print sum}'

在文件中我找到了31G堆内存的映射:
在这里插入图片描述
其中的Rss刚好等于31G。
而剩下内存的大部分被lucene文件占用,我把lucene文件目录部分的过滤出来,统计的Rss和有22G之多。
过滤和统计lucene文件占用RSS的命令如下:

grep -A 5  'SERVICE-ELASTICSEARCH' smaps > lucene_smaps
grep Rss lucene_smaps |awk 'BEGIN {sum = 0;} {sum += $2} END{print sum}'

现在基本可以确定内存超出控制的元凶就是lucene文件的加载。而lucene文件所占用的内存即不属于JVM的堆内存,也不属于MaxDirectMemorySize 控制的堆外内存。因此这块内存是不受ES进程控制的。那么为什么会加载这些Lucene文件呢?

这不得不让我想到了ES的文件存储类型。
5.6.4版本的ES支持simplefs,niofs,mmapfs这3中文件存储类型,配置配置项index.store.type进行配置。可参考:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/index-modules-store.html
我的环境默认使用的是mmapfs。这种存储类型会将lucene索引文件用mmap的方式映射到内存中,这样进程就能够直接从内存中读取lucene数据了。对mmap不了解可以参考:https://www.jianshu.com/p/da998d55ea36

由于使用了内存映射,es进程读取lucene文件的时候读取到的数据就会占用了堆外内存的空间,数据读取完毕后这块内存空间会自动释放。用于我的es环境在压测,因此高并发,不间断的查询使得越来越多的数据被读入堆外内存空间,导致ES进程的总体内存不断上升。

问题解决

虽然es进程占用的内存因为加载lucene文件而升高,但这并不会成为一个问题,因为mmapfs占用的内存是缓存类型的,当其他进程使用到这块内存区域的时候,它将会释放。

如果还是不放心,不希望看到RES指标持续增长的现象,可以将mmapfs模式修改为niofs。这样es就不会使用内存映射的方式了,堆外内存空间也不会上升,RES指标也就稳定了。不过官方还是推荐64位的linux系统使用mmapfs模式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值