MongoDB内存过高问题分析及解决

 更新时间:2024年03月29日 08:27:29   作者:运维开发笔记  
有个3.2.7版本的mongo复制集,最近几天频繁告警内存过高,所以这篇文章给大家介绍了MongoDB内存过高问题分析及解决。并通过代码示例给出详细的解决方案,需要的朋友可以参考下

告警

公司有个3.2.7版本的mongo复制集,最近几天频繁告警内存过高。

服务器配置16C+64G内存。mongo备节点内存使用到55G,触发告警。

以下内容基于3.2.7版本,3.2.7版本已经太老,很多后来的命令和配置,3.2.7都没有。

排查

排查mongo配置

主要是检查cacheSizeGB

  wiredTiger:
     engineConfig:
          cacheSizeGB: 20

MongoDB 3.2 及以后,默认使用 WiredTiger 存储引擎,可通过 cacheSizeGB 选项配置 WiredTiger 引擎使用内存的上限,一般建议配置在系统可用内存的一班左右。

默认值是(RAM – 1GB) / 2。出发点是防止系统OOM kill。因为这里的配置只是wiredTiger的内存cache限额,并不是mongo的全部使用内存限额,整个mongo进程的内存占用要比这个值大,所以cacheSizeGB万万不可设置超过RAM的60%。

我们这里配置到了20G。但是实际运行中发现,在并发查询很高的情况下,wt的cacheSize还是会超过这个配置一点点。

查看mongo实例的内存使用情况

db.serverStatus().wiredTiger.cache

返回结果中 bytes currently in the cache 后的值为缓存数据的大小

...
"bytes currently in the cache" : 21483838298,
...

已经用满了,这种情况可以加一下内存了。但是内存太贵,业务也没有那么高的性能要求,保障不宕机是更有性价比的方案。

既然cache只用了20G,

看看tcmalloc的情况

db.serverStatus().tcmalloc
------------------------------------------------
MALLOC:    22351254936 (21315.8 MiB) Bytes in use by application
MALLOC: +  24922800128 (23768.2 MiB) Bytes in page heap freelist
MALLOC: +    449403872 (  428.6 MiB) Bytes in central cache freelist
MALLOC: +       262144 (    0.2 MiB) Bytes in transfer cache freelist
MALLOC: +    841870984 (  802.9 MiB) Bytes in thread cache freelists
MALLOC: +    109572256 (  104.5 MiB) Bytes in malloc metadata
MALLOC:   ------------
MALLOC: =  48675164320 (46420.3 MiB) Actual memory used (physical + swap)
MALLOC: +   8663441408 ( 8262.1 MiB) Bytes released to OS (aka unmapped)
MALLOC:   ------------
MALLOC: =  57338605728 (54682.4 MiB) Virtual address space used
MALLOC:
MALLOC:         378600              Spans in use
MALLOC:           1451              Thread heaps in use
MALLOC:           8192              Tcmalloc page size
------------------------------------------------
Call ReleaseFreeMemory() to release freelist memory to the OS (via madvise()).
Bytes released to the OS take up virtual address space but no physical memory.

可以看到page heap freelist占了大头。

解释一下,57338605728 (54682.4 MiB) Virtual address space used 是mongo总的使用的虚拟内存。

48675164320 (46420.3 MiB) Actual memory used (physical + swap)是mongo总的使用的实际内存。(我没有开swap)

实际内存又分成两部分,freelist中的和非freelist的。freelist的就是已经分配后来又用完释放的内存,存在这个freelist数据结构中,已备后面重用这些内存,我的理解就是我用完了,但是我先拿着。这样后面的业务来了,mongo就不需要再向os申请分配内存这一步了,从性能和效率的维度来看更好。

但是缺点是内存一直没有还给os,导致os角度来看,内存的使用率很高。

tcmalloc 为性能考虑,每个线程会有自己的 local free page cache,还有 central free page cache;内存申请时,按 local thread free page cache ==> central free page cache 查找可用内存,找不到可用内存时才会从堆上申请;当释放内存时,也会归还到 cache 里,tcmalloc 后台慢慢再归还给 OS操作系统, 多数情况下,内存使用率高的原因是 tcmalloc 未能及时将内存归还给操作系统,导致内存最大可能达到几十GB。mongo为了提高性能,倾向于利用os上尽可能多的内存。

解决

所以可以将freelist的内存及时释放给os,可以解决内存水位过高的问题。

db.adminCommand({setParameter:1,tcmallocAggressiveMemoryDecommit:1})

tcmallocAggressiveMemoryDecommit 是一个服务器参数,用于控制 TCMalloc 内存分配器在什么程度上积极地将不再使用的内存释放回操作系统。当设置为 1(开启状态)时,tcmallocAggressiveMemoryDecommit 会使 TCMalloc 更积极地释放不再使用的内存。这意味着当应用程序释放内存后,TCMalloc 会尝试将这部分内存标记为空闲并返回给操作系统,而不是保留在进程的地址空间中以便快速重用。

以上就是MongoDB内存过高问题分析及解决的详细内容,更多关于MongoDB内存过高的资料请关注脚本之家其它相关文章!

相关文章

  • MongoDB快速入门笔记(四)之MongoDB查询文档操作实例代码

    MongoDB快速入门笔记(四)之MongoDB查询文档操作实例代码

    MongoDB 是一个基于分布式文件存储的数据库。接下来通过本文给大家介绍MongoDB快速入门笔记(四)之MongoDB查询文档操作实例代码,感兴趣的朋友一起学习吧
    2016-06-06
  • mongodb使用心得简单总结

    mongodb使用心得简单总结

    本文整理了一年多以来我常用的MongoDB操作,既有运维层面也有应用层面,内容有浅有深,这也就是我从零到熟练的历程。
    2016-01-01
  • MongoDB 常用的crud操作语句

    MongoDB 常用的crud操作语句

    本篇介绍了 MongoDB 的基本 CRUD 操作,可以看到 MongoDB 的语法极其简洁,而且可以使用链式调用的方式进行操作。操作的参数也很固定,且方法名称很明确,上手来说是很容易的
    2021-06-06
  • mongodb使用docker搭建replicaSet集群与变更监听(最新推荐)

    mongodb使用docker搭建replicaSet集群与变更监听(最新推荐)

    replicaSet和cluster从部署难度相比,replicaSet要简单许多。如果所存储的数据量规模不算太大的情况下,那么使用replicaSet方式部署mongodb是一个不错的选择,这篇文章主要介绍了mongodb使用docker搭建replicaSet集群与变更监听,需要的朋友可以参考下
    2023-03-03
  • 浅析MongoDB之安全认证

    浅析MongoDB之安全认证

    MongoDB是基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。默认情况下,MongoDB实例启动运行时是没有启用用户访问权限控制的,在实例本机服务器上都可以随意连接到实例进行各种操作,MongoDB不会对连接客户端进行用户验证
    2021-06-06
  • 关于mongoDB的聚合操作_aggregate()归纳详解

    关于mongoDB的聚合操作_aggregate()归纳详解

    这篇文章主要介绍了关于mongoDB的聚合操作_aggregate()归纳详解,关系是关联关系的一种,是强的关联关系,聚合是整体和个体之间的关系,聚合关系也是通过实例变量实现的。在聚合关系中,两个类是处在不平等层次上的,一个代表整体,另一个代表部分,需要的朋友可以参考下
    2023-07-07
  • MongoDB数据查询方法干货篇

    MongoDB数据查询方法干货篇

    查询操作在我们日常操作数据库的时候是必不可少的一部分,最近有些空闲时间,所有就将MongoDB数据查询的一些方法技巧总结了处理,这篇文章主要介绍了MongoDB数据查询的相关资料,需要的朋友可以参考借鉴,一起来看看吧。
    2017-05-05
  • windows下安装mongodb以及node.js连接mongodb实例

    windows下安装mongodb以及node.js连接mongodb实例

    本篇文章主要介绍了windows下安装mongodb以及node.js连接mongodb实例,非常具有实用价值,需要的朋友可以参考下
    2017-05-05
  • MongoDb CPU利用率过高问题如何解决

    MongoDb CPU利用率过高问题如何解决

    这篇文章主要介绍了MongoDb CPU利用率过高问题如何解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • MongoDB 内存管理相关总结

    MongoDB 内存管理相关总结

    这篇文章主要介绍了MongoDB 内存管理的相关资料,帮助大家更好的理解和学习使用MongoDB数据库,感兴趣的朋友可以了解下
    2021-03-03

最新评论