buffer/cache内存占用过高原因与解决方法

今天一位群友说他的Linux服务器,经常出现“buffer/cache”内存占用很高,甚至100%的情况。特别是晚上12点以后,到早上六点以前。

先简单申明一下,他的服务器配置是4核4G4M的,就放了两个小网站,网站也没什么流量?

 

在Linux系统中,我们经常用free命令来查看系统内存的使用状态。在一个Centos7的系统上,free命令的显示内容大概是这样一个状态,如下:

buffer/cache

 

原因:

什么是buffer/cache?

buffer和cache是两个在计算机技术中被用滥的名词,放在不通语境下会有不同的意义。在Linux的内存管理中,这里的buffer指Linux内存的:Buffer cache。这里的cache指Linux内存中的:Page cache。翻译成中文可以叫做缓冲区缓存和页面缓存。在历史上,它们一个(buffer)被用来当成对io设备写的缓存,而另一个(cache)被用来当作对io设备的读缓存,这里的io设备,主要指的是块设备文件和文件系统上的普通文件。但是现在,它们的意义已经不一样了。在当前的内核中,page cache顾名思义就是针对内存页的缓存,说白了就是,如果有内存是以page进行分配管理的,都可以使用page cache作为其缓存来管理使用。当然,不是所有的内存都是以页(page)进行管理的,也有很多是针对块(block)进行管理的,这部分内存使用如果要用到cache功能,则都集中到buffer cache中来使用。(从这个角度出发,是不是buffer cache改名叫做block cache更好?)然而,也不是所有块(block)都有固定长度,系统上块的长度主要是根据所使用的块设备决定的,而页长度在X86上无论是32位还是64位都是4k。

 

明白了这两套缓存系统的区别,就可以理解它们究竟都可以用来做什么了。

 

什么是page cache?

Page cache主要用来作为文件系统上的文件数据的缓存来用,尤其是针对当进程对文件有read/write操作的时候。如果你仔细想想的话,作为可以映射文件到内存的系统调用:mmap是不是很自然的也应该用到page cache?在当前的系统实现里,page cache也被作为其它文件类型的缓存设备来用,所以事实上page cache也负责了大部分的块设备文件的缓存工作。

 

buffer cache 与 page cache的区别

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

 

如何回收buffer/cache?

Linux内核会在内存将要耗尽的时候,触发内存回收的工作,以便释放出内存给急需内存的进程使用。一般情况下,这个操作中主要的内存释放都来自于对buffer/cache的释放。尤其是被使用更多的cache空间。既然它主要用来做缓存,只是在内存够用的时候加快进程对文件的读写速度,那么在内存压力较大的情况下,当然有必要清空释放cache,作为free空间分给相关进程使用。所以一般情况下,我们认为buffer/cache空间可以被释放,这个理解是正确的。

 

但是这种清缓存的工作也并不是没有成本。理解cache是干什么的就可以明白清缓存必须保证cache中的数据跟对应文件中的数据一致,才能对cache进行释放。所以伴随着cache清除的行为的,一般都是系统IO飙高。因为内核要对比cache中的数据和对应硬盘文件上的数据是否一致,如果不一致需要写回,之后才能回收。

 

在系统中除了内存将被耗尽的时候可以清缓存以外,我们还可以使用下面这个文件来人工触发缓存清除的操作:

[root@tencent64 ~]# cat /proc/sys/vm/drop_caches
1

 

方法是:

[root@tencent64 ~]# echo 1 > /proc/sys/vm/drop_caches

 

当然,这个文件可以设置的值分别为1、2、3。它们所表示的含义为:

echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。
echo 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。
echo 3 > /proc/sys/vm/drop_caches:表示清除pagecache和slab分配器中的缓存对象。

 

解决方法

 

第一种情况:

服务器在正常情况下,例如:未被攻击。我们完全可以按照上面所讲的,人工来清理缓存。

cache 读磁盘时,数据从磁盘读出后,暂留在缓冲区(cache),为后续程序的使用做准备。

buffer 写磁盘时,先保存到磁盘缓冲区(buffer),然后再写入到磁盘。

只需要操作三条命令:

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

 

第二种情况

但是,非正常情况下,再按照上面那种方法就属于治标不治本,你必须要知道“Linux下查看哪个进程占用CPU或内存最多?“。具体的原因是为什么?例如:有后门、被攻击......,你总不能一直去手工清理吧!因此,我的整个解决步骤如下:

 

1、经过我的排查,我发现有一个网站下面,有几个可疑文件:

quest.sh

quest.bat

quest.vbs

 

2、其中,quest.sh还被加入了crontab定时任务

 

3、最后,再用“安全狗”简单查杀了一下,果然是后门文件,而且还挺多的,虽然说有些可能是误报。

之所以要查杀是因为这位朋友的源码是网上找的,可能不仅仅只有我肉眼发现的这几个文件,或许还有其它的,因此要彻底查杀一下。

执行后门文件

 

4、清理掉相应的后门文件。

关于如何判断是否是执行后门文件?这个就要懂点编程了。还好这源码是PHP的,我可以轻易的识别出来。

注意:crontab定时任务那里也要记得删除。

 

总结:

上面只是给大家一个解决问题的思路,毕竟每个人所遇到的情况是不一样的,只有详细的分析才能得出具体的问题,从而得到准确的答案。

    A+
发布日期:2021年06月21日 13:20:35  所属分类:Linux
最后更新时间:2021-06-21 13:28:27
付杰
  • ¥ 69.0元
  • 市场价:99.0元
  • ¥ 119.0元
  • 市场价:199.0元
  • ¥ 99.0元
  • 市场价:99.0元
  • ¥ 89.0元
  • 市场价:129.0元

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: