记一次由于buff/cache导致服务器内存爆满的问题

目录

前言

复现

登录服务器查看占用内存进程排行

先了解一下什么是buff/cache?

尝试释放buffer/cache

/proc/sys/vm/drop_caches

dirty_ratio

dirty_background_ratio

dirty_writeback_centisecs

dirty_expire_centisecs

drop_caches

page-cluster

swapiness

vfs_cache_pressure


前言

我目前在使用pve作为我的虚拟化系统,我在pve中开了一个centos7作为我的mc服务器系统

我写了个定时任务使用python每天凌晨3点将磁盘中的游戏数据备份到pve宿主机中的raid5阵列中,但是我发现服务器内存总是爆满,我初步判断是执行备份脚本导致的,后面实际测试后发现确实是

复现

我先手动触发一次备份 (后台备份)

nohup python server.py &

等待数据备份完成,在pve中查看服务器内存占用

发现服务器内存已经爆满了

登录服务器查看占用内存进程排行

top -o %MEM
top - 18:09:07 up  9:45,  1 user,  load average: 0.84, 0.36, 0.19
Tasks: 241 total,   2 running, 239 sleeping,   0 stopped,   0 zombie
%Cpu(s):  4.1 us,  4.8 sy,  0.0 ni, 90.6 id,  0.5 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 41034536 total, 17324592 free,  7754368 used, 15955576 buff/cache
KiB Swap:  3145724 total,  3135220 free,    10504 used. 32879168 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                     
10536 root      20   0   43.0g   6.1g  25104 S   4.5 15.6 111:50.22 java                                                                        
 9140 polkitd   20   0 3191660 451248  21032 S   0.0  1.1   8:47.40 mysqld                                                                      
 8882 root      20   0 2379512  69380  25784 S   0.0  0.2   0:44.79 dockerd                                                                     
  872 root      20   0  920636  51408  18904 S   0.0  0.1   2:13.25 node                                                                        
  848 root      20   0  936892  47088  18456 S   0.0  0.1   1:10.98 node                                                                        
 8864 root      20   0 1440692  39356  14624 S   0.0  0.1   0:32.95 containerd                                                                  
 8802 root      20   0  715916  30604   6252 S   0.0  0.1  19:44.84 nattunnel                                                                   
 8734 root      20   0  723448  26208      4 S   9.1  0.1  51:22.65 frpc                                                                        
 8745 root      20   0  723704  24916      4 S   0.0  0.1   2:59.84 frpc                                                                        
 1122 root      20   0  574288  17340   6012 S   0.0  0.0   0:07.49 tuned                                                                       
10472 root      20   0 2089844  16204   1760 S   0.0  0.0   9:55.88 docker-proxy                                                                
 9120 root      20   0  720048  13496   4356 S   0.0  0.0   0:04.49 containerd-shim                                                             
10517 root      20   0  720304  13184   4388 S   0.0  0.0   0:04.79 containerd-shim                                                             
  842 polkitd   20   0  612240  11224   4764 S   0.0  0.0   0:00.39 polkitd                                                                     
  869 root      20   0  626196  11216   6916 S   0.0  0.0   0:03.10 NetworkManager                                                              
10450 root      20   0 1489616   8076   1392 S   0.0  0.0   0:00.08 docker-proxy                                                                
 8326 root      20   0  155288   7584   2368 R  72.7  0.0   1:15.53 python                                                                      
    1 root      20   0  194064   7224   4232 S   0.0  0.0   0:16.54 systemd                                                                     
 9098 root      20   0 1350604   6036   1392 S   0.0  0.0   0:00.21 docker-proxy                                                                
 9104 root      20   0 1489872   6036   1392 S   0.0  0.0   0:00.08 docker-proxy                                                                
10457 root      20   0 1489872   6036   1396 S   0.0  0.0   0:00.08 docker-proxy                                                                
10479 root      20   0 1424080   6028   1384 S   0.0  0.0   0:00.07 docker-proxy                                                                
  599 root      20   0   39056   5972   5648 S   0.0  0.0   0:01.44 systemd-journal                                                             
10494 root      20   0 1489872   5752   1152 S   0.0  0.0   0:00.07 docker-proxy                                                                
  621 root      20   0  127396   5632   2604 S   0.0  0.0   0:00.05 lvmetad                                                                     
 7435 root      20   0  154796   5496   4172 S   0.0  0.0   0:01.03 sshd                                                                        
  635 root      20   0   48392   4864   2880 S   0.0  0.0   0:00.55 systemd-udevd                                                               
 1123 root      20   0  113004   4376   3344 S   0.0  0.0   0:00.08 sshd                                                                        
 1615 postfix   20   0   90088   4308   3260 S   0.0  0.0   0:00.12 qmgr                                                                        
 3313 postfix   20   0   89912   4104   3092 S   0.0  0.0   0:00.06 pickup                                                                      
10501 root      20   0 1424080   3984   1392 S   0.0  0.0   0:00.07 docker-proxy                                                                
 1125 root      20   0  216400   3856   3164 S   0.0  0.0   0:04.15 rsyslogd                                                                    
  850 dbus      20   0   66452   2564   1880 S   0.0  0.0   0:01.13 dbus-daemon                                                                 
 7446 root      20   0  115680   2292   1708 S   0.0  0.0   0:00.39 bash                                                                        
 8436 root      20   0  162272   2272   1532 R  13.6  0.0   0:00.10 top                         

 首当其冲的就是java进程,我之前预想的是如果是使用python备份,应该是python进程占用太多内存,没想到是java,我想了想极有可能是系统的 buffer/cache 导致内存过高,因为内存爆满发生在进行读写操作之后

验证

[root@localhost home]# free -h
              total        used        free      shared  buff/cache   available
Mem:            39G        7.4G        295M        8.7M         31G         31G
Swap:          3.0G         41M        3.0G

buff/cache 竟然有31G 

先了解一下什么是buff/cache?

Buffer cache则主要是设计用来在系统对块设备进行读写的时候,对块进行数据缓存的系统来使用。比如我们在格式化文件系统的时候。

一般情况下两个缓存系统是一起配合使用的,比如当我们对一个文件进行写操作的时候,page cache的内容会被改变,而buffer cache则可以用来将page标记为不同的缓冲区,并记录是哪一个缓冲区被修改了。这样,内核在后续执行脏数据的回写(writeback)时,就不用将整个page写回,而只需要写回修改的部分即可。

Linux内核会在内存将要耗尽的时候,触发内存回收的工作,以便释放出内存给急需内存的进程使用。

既然它主要用来做缓存,只是在内存够用的时候加快进程对文件的读写速度,那么在内存压力较大的情况下,当然有必要清空释放cache,作为free空间分给相关进程使用。所以一般情况下,我们认为buffer/cache空间可以被释放,这个理解是正确的。

但是这种清缓存的工作也并不是没有成本。所以伴随着cache清除的行为的,一般都是系统IO飙高。因为内核要对比cache中的数据和对应硬盘文件上的数据是否一致,如果不一致需要写回,之后才能回收。

尝试释放buffer/cache

sync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。切记释放前最好sync一下,防止丢数据。

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

执行之后发现内存已经正常,基本得出是 buffer/cache 中缓存的数据过多导致的内存爆满

执行之后需要将/proc/sys/vm/drop_caches 的值改成原来的0

echo 0 > /proc/sys/vm/drop_caches

但是我执行这个之后,产生了报错

[root@localhost home]# echo 0 > /proc/sys/vm/drop_caches
-bash: echo: write error: Invalid argument

在研究这个报错之前我们先了解几个概念

/proc/sys/vm/drop_caches

清除缓存策略:
1:手动清除page cache
2:手动清除slab分配器中的对象(包括目录项和inode)
3:手动清除page cache和slab分配器中的对象

0 是系统使用的,手动调整是不行的,而释放之后  /proc/sys/vm/drop_caches 显示为1

这个虽然是显示1,但是这个只是一种状态 echo 1 > /proc/sys/vm/drop_caches 是一次手动清除的行为,不会影响系统的自动清除内存

不过每次都要手动清除内存比较麻烦,我找到一个脚本

#! /bin/bash
# 需要释放内存的,内存使用百分比,可以传参,默认是85%
max_rate=$1
if [ ! "$max_rate" ] ; then
        max_rate=85
fi
echo "max_rate: $max_rate"

total=`free -m | awk 'NR==2' | awk '{print $2}'`
used=`free -m | awk 'NR==2' | awk '{print $3}'`
free=`free -m | awk 'NR==2' | awk '{print $4}'`
rate=$(($used*100/$total));
log=/usr/local/logs/mem.log
echo "===========================" >> $log
date >> $log
echo "current_rate: $rate"
echo "Memory usage | [Total:${total}MB][Use:${used}MB][Free:${free}MB]" >> $log
if [ "$rate" -ge "$max_rate" ] ; then
        sync && echo 1 > /proc/sys/vm/drop_caches
        sync && echo 2 > /proc/sys/vm/drop_caches
        sync && echo 3 > /proc/sys/vm/drop_caches
        echo "OK" >> $log
else
        echo "Not required" >> $log
fi

但是这个脚本是根据总内存来判断的,我使用之后并不能起到效果,我改成了根据 buff/cache 和总内存的百分比来判断是否要进行清理

#!/bin/bash
# 需要释放内存的,缓存占用百分比,可以传参,默认是70%
max_cache_rate=$1
if [ ! "$max_cache_rate" ] ; then
        max_cache_rate=70
fi
echo "max_cache_rate: $max_cache_rate"

total_mem=$(free -m | awk 'NR==2{print $2}')
cache_mem=$(free -m | awk 'NR==2{print $6}')
cache_rate=$((cache_mem*100/total_mem))
log=/usr/local/logs/mem.log
echo "===========================" >> $log
date >> $log
echo "current_cache_rate: $cache_rate%"
echo "Memory usage | [Total:${total_mem}MB][Cache:${cache_mem}MB]" >> $log
if [ "$cache_rate" -ge "$max_cache_rate" ] ; then
        sync && echo 1 > /proc/sys/vm/drop_caches
        sync && echo 2 > /proc/sys/vm/drop_caches
        sync && echo 3 > /proc/sys/vm/drop_caches
        echo "OK, cache memory released" >> $log
else
        echo "Not required to release cache memory" >> $log
fi

每隔30分钟运行一次

*/30 * * * * /usr/bin/sh /home/mem.sh

其他的解决方法
通过这个问题对这个buff/cache 有了了解,我就思考:

linux系统应该可以配置不使用buff/cache吧?

buff/cache 的系统自动回收,是不是也是可以配置自动回收的上限呢?

等等问题。我就找到了以下内容:

修改/etc/sysctl.conf 添加如下选项后就不会内存持续增加

vm.dirty_ratio = 1
vm.dirty_background_ratio=1
vm.dirty_writeback_centisecs=2
vm.dirty_expire_centisecs=3
vm.drop_caches=3
vm.swappiness =100
vm.vfs_cache_pressure=163
vm.overcommit_memory=2
vm.lowmem_reserve_ratio=32 32 8
kern.maxvnodes=3


上面的设置比较粗暴,使cache的作用基本无法发挥。

介绍一下具体的配置项:

dirty_ratio

这个参数控制文件系统的文件系统写缓冲区的大小,单位是百分比,表示系统内存的百分比,表示当写缓冲使用到系统内存多少的时候,开始向磁盘写出数 据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,一般启动上缺省是 10。设1加速程序速度;

dirty_background_ratio

这个参数控制文件系统的pdflush进程,在何时刷新磁盘。单位是百分比,表示系统内存的百分比,意思是当写缓冲使用到系统内存多少的时 候,pdflush开始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时, 应该降低其数值,一般启动上缺省是 5;

dirty_writeback_centisecs

这个参数控制内核的脏数据刷新进程pdflush的运行间隔。单位是 1/100 秒。缺省数值是500,也就是 5 秒。如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作;

dirty_expire_centisecs

这个参数声明Linux内核写缓冲区里面的数据多“旧”了之后,pdflush进程就开始考虑写到磁盘中去。单位是 1/100秒。缺省是 30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。建议设置为 1500,也就是15秒算旧。 

drop_caches

释放已经使用的cache;

page-cluster

该文件表示在写一次到swap区的时候写入的页面数量,0表示1页,1表示2页,2表示4页。

swapiness

该文件表示系统进行交换行为的程度,数值(0-100)越高,越可能发生磁盘交换。

vfs_cache_pressure

该文件表示内核回收用于directory和inode cache内存的倾向

vm.dirty_ratio = 5    #dft 20  %
vm.dirty_background_ratio =5 #dft 10 %
vm.dirty_writeback_centisecs=100 #dft 500 is 5s
vm.dirty_expire_centisecs=300    #dft 30000 is 30s
vm.drop_caches=3  #dft  0
vm.swappiness=100  #dft 60
vm.vfs_cache_pressure=133  #dft 100

目前我在使用的是脚本的方法,其他方法大家也可以试试 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/484224.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年计算机三级|数据库习题整理(自用④)

所有题目均来自【三级数据库技术基础题库】,此博客仅为知识点的补充,用于自主的回顾学习,仅供参考。 选择题 知识点:数据库文件 透明性分级: ①分片透明性 > ②位置透明性 > ③局部数据模型透明性 数据仓库数据…

vector类详解及重要函数实现

🪐🪐🪐欢迎来到程序员餐厅💫💫💫 今日主菜:vector类 主厨:邪王真眼 所属专栏:c专栏 主厨的主页:Chef‘s blog 坚持下去,成功不是目的&a…

阿里二面:谈谈ThreadLocal的内存泄漏问题?问麻了。。。。

引言 ThreadLocal在Java多线程编程中扮演着重要的角色,它提供了一种线程局部存储机制,允许每个线程拥有独立的变量副本,从而有效地避免了线程间的数据共享冲突。ThreadLocal的主要用途在于,当需要为每个线程维护一个独立的上下文…

基于Python3的数据结构与算法 - 20 AVL的旋转

一、二叉搜索树的效率 平均情况下,二叉搜索树进行搜索的时间复杂度为O(lgn)。最坏情况下,二叉搜索树可能非常偏斜。(如下图所示)解决方法: 随机化插入AVL树 二、AVL树 AVL树是一棵自平衡的二叉树AVL树具有以下性质&…

自动驾驶感知新范式——BEV感知经典论文总结和对比(一)

自动驾驶感知新范式——BEV感知经典论文总结和对比(一) 博主之前的博客大多围绕自动驾驶视觉感知中的视觉深度估计(depth estimation)展开,包括单目针孔、单目鱼眼、环视针孔、环视鱼眼等,目标是只依赖于视…

YOLOv8:Roboflow公开数据集训练模型

Roboflow公开数据集 Roboflow是一个提供计算机视觉数据集管理和处理工具的平台。虽然Roboflow本身并不创建或策划公开数据集,但它提供了一系列功能,帮助用户组织、预处理、增强和导出计算机视觉数据集。 官方网站:https://universe.roboflow…

【Leetcode每日一题】 动态规划 - 使用最小花费爬楼梯(难度⭐)(41)

1. 题目解析 题目链接:746. 使用最小花费爬楼梯 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 一、设定状态表 为了解决这个问题,我们首先要明确一个“状态表”。这个状态表其实就是一个记录…

【蓝桥杯知识点】二分查找(超超超详细,再也不会错啦)

考完了计算机三级,蓝桥杯和数学建模的学习也要恢复常态啦!今天,我们来了解一种相对简单但容易出错的算法——二分查找。这里还有一些小方法让二分查找没有那么容易出错,开始学习吧啦啦啦! PS: 文章主要参考…

设计模式学习笔记 - 设计模式与范式 - 创建型:7.原型模式:如何快速地clone一个HashMap散列表

原型模式的原理与应用 如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(或者叫拷贝&#xff0…

Lunule: An Agile and Judicious Metadata Load Balancer for CephFS——论文阅读

SC 2021 Paper 分布式元数据论文阅读笔记 问题 CephFS采用动态子树分区方法,将分层命名空间划分并将子树分布到多个元数据服务器上。然而,这种方法存在严重的不平衡问题,由于其不准确的不平衡预测、对工作负载特性的忽视以及不必要/无效的迁…

解码新时代内存架构:探秘数据在内存中的灵动驻足

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看,已成习惯 创作不易,多多支持! 随着信息技术的飞速发展,我们身处一个数据爆炸的时代。数据的处理和存储方式正日益成为技术革新的重要领域。在新时代的…

【Java】高级篇2:多线程

一、相关概念 注意: 1、不同进程之间不共享内存 2、进程之间的数据交换和通信成本很高 线程调度: 单核CPU与多核CPU: 并行与并发: 二、创建和启动线程 1、概述 2、方式 2.1 方式一:继承Thread类 2.2 方式二&#xf…

Fantasy RPG Spell Pack 2

介绍奇幻角色扮演游戏魔法包VFX,这是为您的Unity奇幻角色扮演游戏提供的终极视觉效果解决方案!这个包包含30个独特的VFX,将为您的法术和能力带来生命,让您的玩家沉浸在魔法和奇迹的世界中。 从令人惊叹的彩虹盾和闪电到旋转门户和召唤圈,这个包有你需要的一切来创造一个真…

GETSHELL方法总结上

渗透的总步骤 1.信息收集找到弱漏洞 2.漏洞挖掘 漏洞验证 3.有一定权限 getshell 4.提权后---渗透 5.内网渗透】 前后台拿shell方法汇总 接下来我们实操一波dedecms也就是织梦cms 如果你们的靶场是空白的 可能是php版本 我们修改为5.2 可能是源码问题 我们不要急着上传…

ChatGPT论文指南|揭秘8大ChatGPT提示词研究技巧提升写作效率【建议收藏】

点击下方▼▼▼▼链接直达AIPaperPass ! AIPaperPass - AI论文写作指导平台 公众号原文▼▼▼▼: ChatGPT论文指南|揭秘8大ChatGPT提示词研究技巧提升写作效率【建议收藏】 目录 1.写作方法 2.方法设计 3.研究结果 4.讨论写作 5.总结结论 6.书…

MySQL--select count(*)、count(1)、count(列名) 的区别你知道吗?

MySQL select count(*)、count(1)、count(列名) 的区别? 这里我们先给出正确结论: count(*),包含了所有的列,会计算所有的行数,在统计结果时候,不会忽略列值为空的情况。count(1),忽略所有的列…

Axure RP 9 for mac中文版密钥激活版下载

Axure RP 9是一款专业的快速原型设计工具,它可以帮助产品设计师、交互设计师和用户体验设计师等创建高保真度、交互性强的原型,以便在产品开发之前进行测试和用户验证。 软件下载:Axure RP 9 for mac中文版密钥激活版下载 该工具具有丰富的功…

2023蓝桥杯C/C++A组省赛 B题: 有奖问答|DFS搜索 、线性dp

题目链接: 1.有奖问答 - 蓝桥云课 (lanqiao.cn) 说明: DFS做法: 因为是填空题,不用考虑超时,首先先考虑暴力做法DFS来做,根据题意,30道题,有一个答题的先后顺序,上一…

【算法篇】逐步理解动态规划1(斐波那契数列模型)

目录 斐波那契数列模型 1. 第N个泰波那契数 2.使用最小花费爬楼梯 3.解码方法 学过算法的应该知道,动态规划一直都是一个非常难的模块,无论是状态转移方程的定义还是dp表的填表,都非常难找到思路。在这个算法的支线专题中我会结合很多力…

Java学习笔记 | Java基础语法 | 03 | 流程控制语句

文章目录 0 前言1.流程控制语句1.1 流程控制语句分类1.2 顺序结构 2.判断语句2.1 if语句1. if语句格式1练习1:老丈人选女婿练习2:考试奖励 2. if语句格式2练习1:吃饭练习2:影院选座 3. if语句格式3练习1:考试奖励 2.2 …