Linux遇到一个内存过高的报警——释放buff/cache

前些天一直受到内存报警,过一段时间就会恢复。由于开发工作有些多,就一直没理它,但是最近几天开始有些频繁了。虽然不影响业务,但是天天报警,还是让人提心吊胆的。因此就抽了一个上午的时间去解决一下这个问题。

排查问题

这台机器安装的是mongodb,因为最近业务增加,内容使用增加是正常的,但是实际的占用内存,也不能达到80%的使用率。

首先,使用free -m 命令 查看一下内存的使用情况,这里简单介绍一下这个命令的返回

total:内存总数
used:已经使用的内存数
free:空闲的内存数
shared:多个进程共享的内存总额
buff/cache:磁盘缓存的大小

发现buff/cache 占用的过高。

其次又分析了一下mongoDB 目前数据占用的空间,是正常的。

分析问题

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

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

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

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

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

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

怎么解决问题?

怎样释放Buff/cache呢?

它是通过proc下的一个文件释放,/proc是一个虚拟文件系统,我们可以通过对它的读写操作做为与kernel实体间进行通信的一种手段.也就是说可以通过修改/proc中的文件,来对当前kernel的行为做出调整.那么我们可以通过调整/proc/sys/vm/drop_caches来释放内存。

具体操作命令如下:

sync
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches

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

但是等到每次报警再去释放,不仅不及时,也不方便,所以我在网上也参考一些文章,写了一个定时释放内存的脚本freemem.sh ,脚本内容如下:

#! /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=/www/wwwlogs/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

脚本有了,需要把脚本配置到crontab中(或者其他的定时任务平台)。

crontab配置如下,每半个小时执行一次:

*/30 * * * * root /root/freemem.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

总结

脚本我们现在的服务器已经在用了,报警的问题也解决了。

修改配置的方法还没有试过,试过后觉得不错请留言反馈!

参考文档:

https://www.iteye.com/blog/neiloid-1290929

解决Linux buffer/cache内存占用过高的办法_ailice001的博客-CSDN博客

在linux下回收cache所使用的物理内存_iteye_16982的博客-CSDN博客

linux定时脚本释放内存,Linux定时释放缓存Shell脚本实现自动化运维_陆家贤的博客-CSDN博客

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Linux 系统中,buff/cache 是操作系统用来缓存磁盘数据的一种机制。当应用程序需要读取磁盘上的数据时,Linux 会先将这些数据缓存到内存中,以提高磁盘读取速度。当应用程序需要使用内存时,缓存数据会被清除,将内存返还给应用程序使用。 如果 buff/cache 内存占用过高,有几种可能的解决办法: 1. 调整 vm.dirty_ratio 和 vm.dirty_background_ratio 参数 vm.dirty_ratio 指定了内存中脏数据所占的最大比例,默认值为 20,意味着当内存中脏数据占用超过 20% 时,系统会开始写入磁盘。vm.dirty_background_ratio 指定了内存中脏数据所占的最小比例,默认值为 10,意味着当内存中脏数据占用低于 10% 时,系统会开始写入磁盘。 可以通过修改这两个参数的值来调整 buff/cache 内存占用。例如,将 vm.dirty_ratio 和 vm.dirty_background_ratio 的值都设置为 5,则系统会更频繁地把脏数据写入磁盘,从而减少内存中的缓存数据。 2. 调整 swappiness 参数 swappiness 是一个控制系统将内存中的数据交换到交换空间的程度的参数。默认值为 60,意味着当内存使用率达到 60% 时,系统会开始把一些数据写入交换空间。可以通过修改 swappiness 的值来调整系统的交换行为,从而影响 buff/cache 内存的占用。 例如,将 swappiness 的值设置为较低的 10,则系统会更倾向于保留内存中的缓存数据,从而减少交换行为,降低 buff/cache 内存占用。 3. 增加物理内存 如果系统中物理内存不足,buff/cache 内存占用就会相对较高。可以通过增加物理内存来减少 buff/cache 内存占用,从而提高系统的性能。 需要注意的是,增加物理内存并不是万能的解决办法,可能存在其他因素导致的 buff/cache 内存占用过高问题。在调整系统参数和增加物理内存之前,需要仔细分析系统的性能瓶颈和内存使用情况,找出问题的根本原因。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值