简介
本文档介绍使用Cisco Policy Suite (CPS)解决高内存使用率问题的过程。
先决条件
要求
Cisco 建议您了解以下主题:
使用的组件
本文档中的信息基于以下软件和硬件版本:
- CPS 20.2
- 统一计算系统(UCS)-B
- MongoDB v3.6.17
本文档中的信息都是基于特定实验室环境中的设备编写的。本文档中使用的所有设备最初均采用原始(默认)配置。如果您的网络处于活动状态,请确保您了解所有命令的潜在影响。
背景信息
Linux拥有各种工具来支持、管理、监控和部署软件应用程序。
添加到产品应用的服务和功能会消耗大量的内存。针对Linux服务器的内存优化不仅使应用程序运行更顺畅、速度更快,而且还降低了数据丢失和服务器崩溃的风险。
要优化Linux计算机的内存,您首先需要了解内存在Linux中如何工作。您可以从内存术语开始,讨论Linux如何处理内存,然后学习如何排除和预防内存问题。
一台计算机可以包含的总内存量取决于操作系统的体系结构。
Linux中的整个内存称为虚拟内存-包括物理内存(通常称为RAM - Randon访问内存)和交换空间。除非添加更多RAM,否则无法增加系统的物理内存。但是,可以通过使用硬盘的交换空间来增加虚拟内存。
RAM确定计算机是否可以处理高内存消耗进程。
来自用户、计算机进程和硬盘驱动器(HDD)的数据将发送到RAM。如果需要,RAM会将其存储并发送回用户或HDD。如果数据需要持久性,RAM会将其发送到中央处理器(CPU)。
要检查计算机中的可用可用空间,可以使用free命令。
[root@installer ~]# free -h
total used free shared buff/cache available
Mem: 11Gi 1.3Gi 2.9Gi 105Mi 7.4Gi 10Gi
Swap: 0B 0B 0B
[root@installer ~]#
问题
Linux服务器会由于各种原因消耗大量的内存。为了快速有效地排除故障,首先,您需要排除最可能的原因。
Java进程:
使用Java实现的应用程序有多种,它们的错误实现或配置可能会导致服务器中的高内存使用率。两个最常见的原因是缓存和会话缓存反模式中的配置错误。
缓存是应用实现高性能的常用方法,但如果应用不正确,最终可能会损害系统性能。错误配置可能会使缓存增长过快,并且为系统中运行的其他进程留下更少的内存。
当存储应用程序的中间状态时,通常使用会话缓存。它允许开发人员按会话存储用户,并便于保存或获取数据对象值。但是,开发人员往往会忘记在以后清理会话缓存数据。
使用Java数据库时,通常使用Hibernate会话来创建连接和管理服务器与数据库之间的会话。但是,当开发人员使用休眠会话时,经常会出现一个错误。休眠会话包含在同一个超文本传输协议(HTTP)会话中,而不是为了线程安全而隔离。这使得应用存储的状态超出了必要的范围,并且只有少数用户,内存使用率会大幅增加。
数据库:
当讨论高内存消耗过程时,必须提及数据库。应用程序在处理用户请求时,对数据库进行多次读取和写入,因此我们的数据库会消耗大量的内存。
以MongoDB数据库为例:为了实现高性能,它应用缓存和索引数据的缓冲区机制。如果您将数据库配置为在对数据库有多个请求时使用最大内存,则Linux服务器中的内存很快就会被耗尽。
CPS内存消耗可以通过使用Grafana图表中的相应KPI或其他监控工具进行监控。如果任何CPS虚拟机(VM)上的内存消耗增加超过默认阈值90%,则CPS会为该虚拟机生成内存不足警报。通过使用free_mem_per设置,可在CPS部署模板中配置此阈值。
确定导致高内存使用率的进程/实用程序:
1. 登录已抛出低内存警报的虚拟机。
2. 导航至/var/log目录并签入top_memory_consuming_processes文件,确定具有高内存消耗率的进程ID (PID)。
******************** Date: Tue May 16 05:06:01 UTC 2023 *****************
PID PPID CMD %MEM %CPU RSS PRI STAT PSR WCHAN NI P
9435 1 /usr/bin/java -XX:OnOutOfMe 26.7 77.9 4353796 5 S<l 2 - -15 *
24139 1 /usr/java/default/bin/java 1.0 0.0 174636 20 Sl 3 - 0 *
2905 2862 /usr/sbin/collectd -C /etc/ 1.0 0.2 169104 20 Sl 1 hrtimer_nanosl 0 *
913 1 /usr/lib/systemd/systemd-jo 0.4 0.1 69364 20 Ss 5 do_epoll_wait 0 *
1513 1 /usr/libexec/platform-pytho 0.1 0.0 27912 20 Ssl 5 - 0 *
3379 2905 /usr/sbin/collectd -C /etc/ 0.1 0.0 23716 20 Sl 3 - 0 *
3377 2905 /usr/sbin/collectd -C /etc/ 0.1 0.0 23712 20 Sl 4 - 0 *
3378 2905 /usr/sbin/collectd -C /etc/ 0.1 0.0 23712 20 Sl 5 - 0 *
3380 2905 /usr/sbin/collectd -C /etc/ 0.1 0.0 23712 20 Sl 5 - 0 *
******************** END *****************
3. 使用此命令验证进程,无论它是应用程序进程还是数据库进程。
#ps -ef | grep <PID>
通过CPS解决高内存利用率问题的过程
在Linux中优化内存非常复杂,修复超载内存需要付出巨大的努力。
方法1.
检测并回收缓存的内存:
在某些情况下,内存不足警报可能是由于Linux内存管理在缓存中分配对象造成的。
评估VM已缓存的内存大小,并触发Linux释放部分缓存内存。
1. 比较两个或多个CPS虚拟机上缓存的内存量,以便在每个虚拟机上运行free -m命令。
[root@dc1-qns01 ~]# free -m
total used free shared buff/cache available
Mem: 15876 5262 4396 808 6217 9628
Swap: 4095 0 4095
[root@dc1-qns01 ~]#
2. 要回收部分非活动缓存内存,请运行此命令。
#free && sync && echo 3 > /proc/sys/vm/drop_caches && echo "" && free
[root@dc1-qns01 ~]# free -m
total used free shared buff/cache available
Mem: 15876 5016 8782 872 2076 9809
Swap: 4095 0 4095
[root@dc1-qns01 ~]#
请注意:
1. 此命令会丢弃可能导致输入输出(IO)和中央处理器(CPU)使用率临时增加的缓存对象,因此建议在非高峰时间/维护时段运行此命令。
2. 这是一个非破坏性命令,并且只有未使用的可用内存。
如果内存不足警报仍未解决,则继续执行方法2。
方法2.
如果高内存消耗是由任何应用进程(如QNS等)造成的。
1. 重新启动进程。
Command Syntax:
#monit restart <process name>
2. 使用free-m命令验证内存使用率是否下降。
如果内存不足警报仍未解决,则继续执行方法3。
方法3.
重新启动已生成警报的虚拟机,因为通常通过重新启动虚拟机来增加虚拟机的资源(磁盘内存CPU)。
如果发现sessionmgr VM的内存使用率较高,则继续执行方法4。
方法4.
1. 登录到已注意到高内存使用率的VM。
2. 导航至/var/log目录,并签入mongodb-<xxxx>.log文件,查找与内存消耗和writeConcernMajorityJournalDefault参数相关的警告/消息。
2022-12-13T00:30:39.012+0200 I REPL [replexec-0] ** WARNING: This replica set node is running without journaling enabled but the
2022-12-13T00:30:39.012+0200 I REPL [replexec-0] ** writeConcernMajorityJournalDefault option to the replica set config
2022-12-13T00:30:39.012+0200 I REPL [replexec-0] ** is set to true. The writeConcernMajorityJournalDefault
2022-12-13T00:30:39.012+0200 I REPL [replexec-0] ** option to the replica set config must be set to false
2022-12-13T00:30:39.012+0200 I REPL [replexec-0] ** or w:majority write concerns will never complete.
2022-12-13T00:30:39.012+0200 I REPL [replexec-0] ** In addition, this node's memory consumption may increase until all
2022-12-13T00:30:39.012+0200 I REPL [replexec-0] ** available free RAM is exhausted.
3. 登录相应的mongoShell并验证mongo protocolVersion和writeConcernMajorityJournalDefault的当前值。
set04:PRIMARY> rs.status().optimes.lastCommittedOpTime.t
NumberLong(0)
set04:PRIMARY>
注意:在mongo协议版本0的NumberLongo/p中,值始终为负值。
set04:PRIMARY> rs.conf().writeConcernMajorityJournalDefault
set04:PRIMARY>
注意:如果输出返回none,则必须考虑writeConcernMajorityJournalDefault该值默认设置为true。
4. 如果protocolVersion是1,writeConcernMajorityJournalDefault值为true,则从各个mongoShell运行这些命令可将值writeConcernMajorityJournalDefault修改为 false.
#cfg=rs.conf()
#cfg.writeConcernMajorityJournalDefault=false
#rs.reconfig(cfg)
5. 验证writeConcernMajorityJournalDefault值是否已更改为false。
set03:PRIMARY> rs.conf().writeConcernMajorityJournalDefault
false
set03:PRIMARY>
6. 使用free-m命令验证内存使用率是否下降。