Linux遇到一个内存过高的报警 |
您所在的位置:网站首页 › 电脑内存自动释放 › Linux遇到一个内存过高的报警 |
前些天一直受到内存报警,过一段时间就会恢复。由于开发工作有些多,就一直没理它,但是最近几天开始有些频繁了。虽然不影响业务,但是天天报警,还是让人提心吊胆的。因此就抽了一个上午的时间去解决一下这个问题。 排查问题这台机器安装的是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_cachessync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 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博客 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |