记录一次服务器内存使用率过高达到90%告警问题排查。_服务物理内存一直90%-程序员宅基地

技术标签: 运维  服务器  

‍个人主页:阿木木AEcru

系列专栏:Docker容器化部署系列

每一次技术突破,都是对自我能力的挑战和超越。

一、前言

在这里插入图片描述
一大早就有一个电话过来:“你快看看,这台服务器怎么一直在告警,90%的使用率,一直下不去”。

作为牛马的我立马就起身了,心里想:我也不是专业运维啊,啥事都来找我。抱着试一试的心态就上了堡垒机看那下。

二、问题排查处理

首先肯定是先看看目前服务器占用的内存信息
在这里插入图片描述
指令描述如下:

free: 这是Linux系统中用于显示内存使用情况的命令。

  1. -s 2: 这个选项指定了更新的时间间隔,单位是秒。在这个例子中,设置为2秒,表示每2秒更新一次内存使用情况。
  2. -c 5: 这个选项指定了输出的次数,即显示内存使用情况的次数。在这个例子中,设置为5,表示输出内存使用情况5次。
  3. -h: 这个选项用于以G为单位显示内存使用情况,以便更容易理解。
    整个指令的作用是每2秒更新一次系统的内存使用情况,并且在终端上显示5次内存使用情况。

输出内容的详细解释如下:

  • total: 总内存量,表示系统中总共的可用内存。
  • used: 已使用的内存量,表示系统当前正在使用的内存。
  • free: 空闲内存量,表示系统中当前未被使用的内存。
  • shared: 多个进程共享的内存量。
  • buffers: 用于缓冲的内存量,通常用于临时存储I/O操作的数据。
  • cached: 用于缓存的内存量,通常用于存储最近使用过的数据,以提高系统性能。
  • available: 可用内存量,表示系统中可供进程使用的内存量,包括空闲内存和缓存。

从这里很容易就看出了可用内存仅剩 1.4G 了,但是已使用内存只用了1.5G。

相信大家也看到了 buffers/cached 占用了 12G 之多,而这个就是罪魁祸首。缓存中的数据大部分都是磁盘文件 数据,是为了提高io。而缓存中的内存是可以被自动释放以及手动释放的。当内存短缺的时候系统会进行自动释放。当然手动释放也是很简单的。通过以下命令即可

sync && echo 3 > /proc/sys/vm/drop_caches

sync 用于将内存中的数据同步到磁盘中,所以在清理最好还是先执行此命令,以防数据丢失。
echo 3 > /proc/sys/vm/drop_caches 是将 3  写入到 该文件中,其作用是作用系统中的缓存。
如果写入数字 1,则会清除页缓存(page cache)。
如果写入数字 2,则会清除目录项缓存(dentry cache)。
如果写入数字 3,则会同时清除页缓存和目录项缓存。

可当我执行完成之后发现, buffers/cached 还是占用了12G ,那说明这里的缓存已经不是通过释放能解决的了。

我就在想, 是什么东西占用了这么多内存,也通过了top命令看了,没有发现什么异常的情况。于是我就想看看是什么占用了这么多内存。 在网上找到,可以在 /proc/meminfo 文件中 查看 当前系统内存使用情况详情。执行后如下
在这里插入图片描述
参数解释:

MemTotal: 系统可用的总内存大小,单位为kB(千字节)。
MemFree: 当前未被使用的内存大小,单位为kB。
MemAvailable: 估计当前可用的内存大小,单位为kB。该值是根据当前系统负载和进程执行需要估计出的可用内存大小。
Buffers: 用于存放文件系统的缓存的内存大小,单位为kB。
Cached: 用于存放缓存的内存大小,单位为kB。缓存包括文件系统缓存和页面缓存。
SwapCached: 用于存放交换缓存的内存大小,单位为kB。
Active: 当前活跃的内存大小,单位为kB。活跃内存指正在被使用的内存。
Inactive: 当前不活跃的内存大小,单位为kB。不活跃内存指最近未被访问的内存。
Active(anon): 当前活跃的非匿名内存大小,单位为kB。
Inactive(anon): 当前不活跃的非匿名内存大小,单位为kB。
Active(file): 当前活跃的文件缓存内存大小,单位为kB。
Inactive(file): 当前不活跃的文件缓存内存大小,单位为kB。
Unevictable: 无法被交换出内存的大小,单位为kB。
Mlocked: 已锁定的内存大小,单位为kB。
SwapTotal: 交换空间的总大小,单位为kB。
SwapFree: 交换空间中当前可用的大小,单位为kB。
Dirty: 当前等待被写回磁盘的脏页大小,单位为kB。
Writeback: 当前正在被写回磁盘的页大小,单位为kB。
AnonPages: 匿名页的大小,单位为kB。匿名页指进程私有的内存页,无法被其他进程共享。
Mapped: 已被映射到进程地址空间的页的大小,单位为kB。
Shmem: 共享内存的大小,单位为kB。
Slab: 内核内存管理缓存的大小,单位为kB。
SReclaimable: 可回收的Slab内存大小,单位为kB。
SUnreclaim: 不可回收的Slab内存大小,单位为kB。
KernelStack: 内核栈的大小,单位为kB。
PageTables: 存放页表所占用的内存大小,单位为kB。
NFS_Unstable: 不稳定NFS内存大小,单位为kB。
Bounce: 弹跳缓冲区大小,单位为kB。
WritebackTmp: 临时的待写回页大小,单位为kB。
CommitLimit: 当前系统支持的最大内存使用量,单位为kB。
Committed_AS: 已分配但还未分配物理内存的内存大小,单位为kB。
VmallocTotal: 可用的虚拟内存大小,单位为kB。
VmallocUsed: 已使用的虚拟内存大小,单位为kB。
VmallocChunk: 最大可分配的单个虚拟内存块大小,单位为kB。
HardwareCorrupted: 硬件错误导致的内存损坏大小,单位为kB。
AnonHugePages: 匿名巨页的大小,单位为kB。
CmaTotal: 连续内存区域的总大小,单位为kB。
CmaFree: 当前可用的连续内存区域的大小,单位为kB。
HugePages_Total: 巨页的总数量。
HugePages_Free: 当前可用的巨页数量。
HugePages_Rsvd: 保留的巨页数量。
HugePages_Surp: 超过总数量的巨页数量。
Hugepagesize: 巨页的大小,单位为kB。
DirectMap4k: 直接映射到物理内存的4KB页面的大小,单位为kB。
DirectMap2M: 直接映射到物理内存的2MB页面的大小,单位为kB。
DirectMap1G: 直接映射到物理内存的1GB页面的大小,单位为kB。
从这里就能看出问题了, 在slab 内核内存管理缓存 就占用了大部分, 而且在 SUnreclaim 中就能看出 大部分是不可以被回收的。

导致slab 缓存这么巨大的原因可能有哪些呢?

1、频繁的内存分配和释放:如果系统中有大量的进程或应用程序频繁地进行内存分配和释放操作,就会导致 Slab 缓存中的内存不断增长。这可能是因为系统在分配内存时无法满足连续的内存需求,导致内核频繁地使用 Slab 分配器进行小块内存的分配。
2、过多的文件系统缓存:文件系统缓存(Cached)也是由 Slab 缓存来管理的。如果系统中有大量的文件被读取到内存中,并且没有及时释放,就会导致 Cached 缓存占用过多的内存,进而导致 Slab 缓存占用过大。
3、内核模块的使用:内核模块也会使用 Slab 缓存来管理内存。如果系统中有大量的内核模块被加载,并且这些模块占用了大量的内存,就会导致 Slab 缓存占用过大。
4、内核bug:在一些情况下,可能会存在内核中的 bug 导致 Slab 缓存占用过大。这可能是由于内核中的内存管理机制存在问题,导致 Slab 缓存无法正确地释放内存

到这,我就知道了,因为这台服务器是用做文件存储,应该是比较久之前开发的时候用了 openssh,没有用到专门的对象存储应用,然后留下的坑。频繁的文件操作导致了 slab缓存的累积,只增不减,就出现了这个问题。

然后就去查了怎么看slab 中 的使用情况 。 使用 slabtop 指令就可以查看了。情况如下:

在这里插入图片描述
从这里就能看出来被kmalloc占用了大部分,而这个kmalloc又是什么?

在 Linux 内核中,kmalloc 是一种用于动态分配小块内存的函数。它是 Slab 分配器中的一部分,用于分配大小小于等于页面大小的内存块。kmalloc 主要用于内核中的数据结构、缓冲区和其他小型对象的动态分配。

kmalloc 函数的一些特点和用途:

分配小块内存:kmalloc 函数用于分配大小小于等于页面大小(通常为4KB或更大)的内存块。它通常用于分配小型数据结构、缓冲区和其他小型对象所需的内存。
支持高速缓存:kmalloc 分配的内存块可以被 Slab 分配器缓存,以提高分配和释放内存的速度。这意味着相同大小的内存块可能会被缓存起来,以便下次分配时可以更快地完成。
对齐要求:kmalloc 分配的内存块通常会按照一定的对齐要求进行分配。这可以确保分配的内存块在物理内存中的地址是对齐的,以提高访问效率。
实现方式:kmalloc 函数的具体实现会根据系统架构和内核版本而有所不同。在实现上,它可能会调用底层的物理内存分配器,如 Buddy 系统或 Slab 系统,以分配所需大小的内存块。

接下来也找了很久,也没有发现什么好的解决方案,然后目前就是准备重启服务器来解决问题了。如果各位大佬有什么好的解决方案还麻烦在评论区指导一二,感谢!

三、 结尾

感谢您的观看! 如果本文对您有帮助,麻烦用您发财的小手点个三连吧!您的支持就是作者前进的最大动力!再次感谢!

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

智能推荐

linux 命令学习_ls `pwd`/*-程序员宅基地

文章浏览阅读6.5k次。作为一个程序员,我们在进行项目部署和运维时,经常会用到一些linux命令,可是这些命令老是忘记,每次用到的时候都要去谷歌百度,很是麻烦!这不,为了自己使用方便,对常见的linux命令进行了系统的总结,以便在用到时能够快速地找到相关命令,同时有需要的朋友也可以参考搜藏该篇文章!文章对讲到的每个命令都有详细的参数解释,并且给出一些常用例子,因此也非常适合用来学习!全文命令分为以下6个模块:1、常用系统工作命令2、系统状态检测命令3、工作目录切换命令4、文本文件编辑命令5、文件目录管理命令6、打包._ls `pwd`/*

javax.servlet.ServletException: Servlet[SpringMvc]的Servlet.init()引发异常处理-程序员宅基地

文章浏览阅读2.9w次,点赞10次,收藏16次。javax.servlet.ServletException: Servlet[SpringMvc]的Servlet.init()引发异常处理分析错误描述错误原因分析原因解决办法分析关于javax.servlet.ServletException: Servlet[SpringMvc]的Servlet.init()引发异常处理情况Servlet[SpringMvc]的Servlet.init()引发异常错误描述Servlet[SpringMvc]的Servlet.init()引发异常创建Ser_javax.servlet.servletexception: servlet[springmvc]的servlet.init()引发异常

centos7 文件搜索、文件内容搜索、管道_centos7搜索变量属于那个文件-程序员宅基地

文章浏览阅读1.9k次。1、文件搜索find 可以找到你想要的文件格式: find [目录] [选项] [选项值]目录:去哪找,可以不写,默认代表当前目录选项:怎么找 >> -name 按照名字找 可以使用通配符 -size 按照大小找 单位为 kmg 10k(等于10k) +10k(大于10k) -10k(小于10k) -user 按照用户名 -group 按照组名 -maxdepth -minde_centos7搜索变量属于那个文件

keepalived + lvs集群_lvs client在lb节点请求vip-程序员宅基地

文章浏览阅读115次。1.keepalived是什么? keepalived是集群管理中保障集群高可用的一个服务软件,其功能类似于heartbeat,用来防止单点故障 2.keepalived 工作原理keepalived是以**VRRP**协议为实现基础的,VRRP全称Virtual Route Redundancy Protocol,即**虚拟路由冗余协议** ..._lvs client在lb节点请求vip

Spring AOP 原理 (面试必备)_springaop实现原理面试-程序员宅基地

文章浏览阅读5.9w次,点赞21次,收藏179次。一、AOP是什么? AOP的全称是Aspect Orient Programming,即面向切面编程。是对OOP(Object Orient Programming)的一种补充,战门用于处理一些具有横切性质的服务。常常用于日志输出、安全控制等。 上面说到是对OOP的一种补充,具体补充的是什么呢?考虑一种情况,如果我们需要在所有方法执行前打印一句日志,按照OOP的处理思想,我们需要..._springaop实现原理面试

shell脚本特殊变量意义_在shell脚本里下面哪些特殊符号可以用来表示所有向脚本传递的参数-程序员宅基地

文章浏览阅读358次。Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数特殊变量列表变量 含义$0 当前脚本的文件名$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。$# 传递给脚本或函数的参数个数。$* 传递给脚本或函数的所有参数。$@ 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* _在shell脚本里下面哪些特殊符号可以用来表示所有向脚本传递的参数

随便推点

vue3中借助 pdfjs-dist 实现pdf文件展示、文本选中功能及使用过程中部分问题处理_vue3对pdf文件操作文件选取-程序员宅基地

文章浏览阅读2.6k次,点赞30次,收藏30次。一、文件预览1、安装 `pdfjs-dist` ,此处指定版本为 `2.16.105`2、`html` 结构内容3、`js` 功能实现:4、可能出现的问题(1) 部分字体出现乱码或浏览器控制台出现警告二、文本选中1、功能实现2、可能出现的问题:(1) 页面文字可选中,但文本不可见(2) 浏览器控制台报错 `Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'dispatch_vue3对pdf文件操作文件选取

二叉树的先序+中序+后序的遍历非递归版本_后序遍历,第一个访问的节点-程序员宅基地

文章浏览阅读139次。先序遍历递归版本很简单,学习一下非递归的写法。先遍历根节点,再遍历左儿子,最后遍历右儿子def preOrder(root): # 返回先序遍历序列 if not root: return [] p = root res = [] stack = [] while stack or p: ..._后序遍历,第一个访问的节点

springboot+mybatis+dubbo+redis简单整合_springboot、dubbo和mybatisplus和redis搭建工程如何自动生成pom依赖-程序员宅基地

文章浏览阅读3.7k次,点赞2次,收藏11次。一、创建一个接口maven项目 里面存放服务的接口与实体类,在本地仓库安装(install)一下接口服务,目录结构User就是简单的pojo实体类,在UserService中提供了两个接口方法package com.fhh.springboot.service;import com.fhh.springboot.Entity.User1;/** * 功能描述:(..._springboot、dubbo和mybatisplus和redis搭建工程如何自动生成pom依赖

FAT32分区被格式化了数据恢复方法-程序员宅基地

文章浏览阅读681次。恢复背景--早上不小心将FAT32分区格式化,需要恢复格式化之前的数据,但现在这个盘是空盘了,如图 已用空间16KB ,总容量30GB . 为什么格式化了 ,已用空间还有16KB呢。 这是因为FAT32文件系统格式化时 会对根目录清零 ,根目录占用一个簇的大小,所以这里看到已用空间占了16KB。 有的电脑可能会看到格式化后占用8KB或者32KB,原因都一样 只是因为格式化时..._2、如果不小心将u盘的fat32文件系统中数据格式化了,我们可以采用哪些工具恢复。若要手工恢复使用winhex工具,恢复的思路是什么?

安装mysql服务出现Install/Remove of the Service Denied!问题,即使管理员启动cmd也无效_install/remove of the service denied! that operati-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏20次。在禁用 UAC 后,系统将不再提示 UAC 提示框,直接以管理员权限运行命令,从而避免了 UAC 的干扰。但是,禁用 UAC 会降低系统的安全性,因为这会使得恶意软件有更大的机会在计算机上运行和执行操作,因此不建议在正式生产环境中禁用 UAC。UAC(用户帐户控制)是 Windows 操作系统的一项安全特性,用于控制用户在计算机上的活动,以减少恶意软件或病毒的危害。在Windows系统下,如果你是以管理员身份运行cmd,但是仍然无法安装MySQL服务,可能是因为系统的用户账户控制(UAC)设置的问题。_install/remove of the service denied! that operation should be made by an us

ensp查看历史配置命令_eNSP常用命令.doc-程序员宅基地

文章浏览阅读1.5k次。eNSP常用命令3、acl命令格式基本/高级 ACL 支持:acl [ ipv6 ] acl-number { inbound | outbound }undo acl [ ipv6 ] acl-number { inbound | outbound }二层 ACL 支持:acl acl-number inboundundo acl acl-number inbound功能:acl 命令用来引用访..._ensp历史命令查看

推荐文章

热门文章

相关标签