目录

一、什么是buffer/cache?

buffer/cache 其实是作为服务器系统的文件数据缓存使用的,尤其是针对进程对文件存在 read/write 操作的时候,所以当你的服务进程在对文件进行读写的时候,Linux内核为了提高服务的读写速度,则将会把文件放在此处的 buffer/cache 中进行缓存使用,由于 Linux服务的特点便是任何事物都会以文件的形式进行存在,所以你会发现不管你是否对文件做了大规模的读写,机器的 buffer/cache 是一直都存在的,并且持续的增高不下,这是因为服务器所产生的网络连接也好,用户协议的(UDP)套接字也好,这部分的数据系统都会为应用程序创建对应的文件描述符,而这些文件描述符的使用,则又都会重新进入 buffer/cache 中做读写使用,所以这也是你的机器始终都会存在较高 buffer/cache 的原因!(因为所有的文件读写都会用到 buffer/cache,在内存合理的情况下)

二、什么是page cache?

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

三、buffer/cache 需要注意的一些特点

在服务内存够用的情况下,Linux内核为了加快对文件的读写效率会将文件放入之 buffer/cache 中 以保证读写效率,但其实,尽管当你的应用程序对文件的读写运行结束后,buffer/cache 也不会自动释放该部分内存,而是作为缓冲进行保留,等到你的服务进程在下一次进行相同文件的读写时就可以直接使用,省去了各种重新进行内存初始化的操作;所以这将会导致,当你的应用进程频繁对不同的文件进行读写时,你会发现服务所可以直接使用的free内存将会越来越少的一个重要原因;难道 buffer/cache 在这样无休止的缓存当中就不会自动释放?当然不是,当服务器在内存压力较大的情况下时,则将会自动进行内存的回收,作为free空间分给其它进程使用,这其中主要回收的一个内存则是 buffer/cache 的缓冲区内存块;

四、如何进行手动 buffer/cache 回收?

除了在系统进程内存使用较大压力的情况下进行内存的回收外,我们也可以进行手动的buffer/cache回收,但由于buffer/cache主要是用于文件的读写使用,所以进行文件回收时,一般常伴随系统的IO彪高,因为系统内核也对比cache中的数据与硬盘中的数据是否一致,如果不一致需要写入,然后才能进行内存的回收;

$ sync
# 将内存中数据强制先刷新到磁盘中

清理Buffer缓存区域
$ 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分配器中的缓存对象

如果你必须清除磁盘高速缓存,第一个命令在企业和生产环境中是最安全"...echo 1> ..."只会清除页面缓存。 在生产环境中不建议使用上面的第三个选项"...echo 3 > ..." ,除非你明确自己在做什么,因为它会清除缓存页,目录项和inodes。

在Linux上释放也许被内核所使用的缓冲区(Buffer)和缓存(Cache)是否是个好主意?

当你设置许多设定想要检查效果时,如果它实际上是专门针对 I/O 范围的基准测试,那么你可能需要清除缓冲区和缓存。你可以如上所示删除缓存,无需重新启动系统(即无需停机)。

Linux被设计成它在寻找磁盘之前到磁盘缓存寻找的方式。如果它发现该资源在缓存中,则该请求不会发送到磁盘。如果我们清理缓存,磁盘缓存就起不到作用了,系统会到磁盘上寻找资源。

此外,当清除缓存后它也将减慢系统运行速度,系统会将每一个被请求的资源再次加载到磁盘缓存中。

现在,我们将创建一个 shell 脚本,通过一个 cron 调度任务在每天下午2点自动清除RAM缓存。如下创建一个 shell 脚本 clearcache.sh 并在其中添加以下行:

 #!/bin/bash
 # 注意,我们这里使用了 "echo 3",但是不推荐使用在产品环境中,应该使用 echo 1
 echo 3 > /proc/sys/vm/drop_caches"

给clearcache.sh文件设置执行权限

 # chmod 755 clearcache.sh

现在,当你需要清除内存缓存时只需要调用脚本。

现在设置一个每天下午2点的定时任务来清除RAM缓存,打开crontab进行编辑。

 # crontab -e

添加以下行,保存并退出。

 0 3 * * * /path/to/clearcache.sh

五、buffer/cache 过高如何排查是由那几个进程引起的

5.1 hcache安装

$ wget https://silenceshell-1255345740.cos.ap-shanghai.myqcloud.com/hcache -O /usr/local/bin/hcache ;\
chmod +x /usr/local/bin/hcache

5.2 hcache常用命令

$ hcache --top 10           # 全局显示10个最大的被缓存文件
$ lsof /usr/lib/vmware-tools/lib64/libxerces-c-3.1.so/libxerces-c-3.1.so
# 根据文件找到对应的进程、pid
$ hcache -pid 1070   # 获取当前进程号所打开的所有文件信息
$ lsof -p 1070     # 获取当前进程号所打开的所有文件信息(二选一)

lsof命令使用参考网址:https://man.linuxde.net/lsof

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐