Linux下的Cache/Buffer

一、含义

  • Cache(缓存):指 CPU 和内存之间高速缓存,为了调高CPU和内存之间数据交换而设计,用来给文件做缓存(相关的是PageCache),主要是针对读操作设计的;

  • Buffer(缓冲):指在写入磁盘前的存储在内存中的内容,为了提高内存和硬盘(或其他I/O设备的数据交换而设计),主要是针对写操作设计的;

Cache/Buffer所处位置图解

下面为Linux下free指令显示的信息,以下简单描述一下各选项的含义:

[root@* ~]# free -g
total used free shared buff/cache available
Mem: 125 2 109 1 13 120
Swap: 7 0 7
  • Mem:表示物理内存的统计信息;
  • Swap:表示磁盘上交换分区的使用情况;
  • total:总的内存大小;
  • used:已经使用的内存大小(包含buff/cache和shared的大小);
  • free:空闲的内存大小;
  • shared:进程间的内存大小;
  • buff:写磁盘的数据在内存中缓存的数据大小,能够快速响应,后续会将数据定期刷到磁盘上;
  • cache:读取的数据在内存中缓存的数据大小,下次读取时能够快速返回;
  • available:真正可用的内存大小;

二、缓存相关脚本

2.1、缓存清理方式

  • 清理pagecache(页面缓存):

    echo 1 > /proc/sys/vm/drop_caches # sysctl -w vm.drop_caches=1
  • 清理dentries(目录的数据结构)和inodes(文件的数据结构):

    echo 2 > /proc/sys/vm/drop_caches # sysctl -w vm.drop_caches=2
  • 清理pagecache(页面缓存)、dentries(目录的数据结构)和inodes(文件的数据结构):

    echo 3 > /proc/sys/vm/drop_caches # sysctl -w vm.drop_caches=3

2.2、缓存使用分析

2.2.1、slabtop指令

内核的模块在分配资源的时候,为了提高效率和资源的利用率,都是透过slab来分配的。通过slab的信息,再配合源码能粗粗了解系统的运行情况,比如说什么资源有没有不正常的多,或者什么资源有没有泄漏。Linux系统透过/proc/slabinfo来向用户暴露slab的使用情况。

Linux所使用的 slab 分配器的基础是Jeff BonwickSunOS 操作系统首次引入的一种算法。Jeff 的分配器是围绕对象缓存进行的。在内核中,会为有限的对象集(例如文件描述符和其他常见结构)分配大量内存。Jeff 发现对内核中普通对象进行初始化所需的时间超过了对其进行分配和释放所需的时间。因此他的结论是不应该将内存释放回一个全局的内存池,而是将内存保持为针对特定目而初始化的状态。Linux slab 分配器使用了这种思想和其他一些思想来构建一个在空间和时间上都具有高效性的内存分配器。

使用slabtop命令可以实时的显示内核中slab缓冲区的细节信息,相关选项参数为:

--delay=n, -d n:每n秒更新一次显示的信息,默认是每3秒;
--sort=S, -s S:指定排序标准进行排序(排序标准,参照man手册);
--once, -o:显示一次后退出;
--version, -V:显示版本;
--help:显示帮助信息。

slabtop运行状态示意图

2.2.2、使用fincore©或pcstat(Go)分析程序的cache的占用

fincorelinux-ftools工具集中的一个工具,其他的工具还有fallocatefadviselinux-ftools项目原来在Google Code上进行维护,但是Google Code已经在2016年就停止维护了,不过依旧可以在Github上寻找到该项目,目前我也将该项目迁移到了我自己的Github主页上,并做了一些简单的变动,项目地址为:bugwz/linux-ftools,fincore的编译安装在项目中有详细介绍。

pcstat工具实现了与fincore相同的功能,并且输出效果看起来更为优雅,不过目前这里只演示fincore的工具使用。

fincore工具运行如下所示:

[root@*-self linux-ftools]# ./fincore
fincore version 1.0.0
fincore [options] files...

--pages=false Don't print pages
--summarize When comparing multiple files, print a summary report
--only-cached Only print stats for files that are actually in cache.

使用fincore工具配合Shanker提供的脚本,即可简单的查看cache的占用情况,相关脚本如下所示:

#!/bin/bash
#Author: Shanker
#Time: 2016/06/08
#set -e
#set -u
#you have to install fincore
if [ ! -f /usr/local/bin/fincore ]
then
echo "You haven't installed fincore yet"
exit
fi
#find the top 10 processs' cache file
ps -e -o pid,rss | sort -nk2 -r | head -10 | awk '{print $1}' > /tmp/cache.pids
#find all the processs' cache file
#ps -e -o pid > /tmp/cache.pids
if [ -f /tmp/cache.files ]
then
echo "The cache.files is exist, removing now "
rm -f /tmp/cache.files
fi
while read line
do
lsof -p $line 2>/dev/null | awk '{print $9}' >> /tmp/cache.files
done < /tmp/cache.pids
if [ -f /tmp/cache.fincore ]
then
echo "The cache.fincore is exist, removing now"
rm -f /tmp/cache.fincore
fi
for i in `cat /tmp/cache.files`
do
if [ -f $i ]
then
echo $i >> /tmp/cache.fincore
fi
done
fincore -s `cat /tmp/cache.fincore`
rm -f /tmp/cache.{pids,files,fincore}

执行脚本的结果如下所示:

     Name         Size(bytes)   TotalPages  CachedPages   CachedSizes     CachedPercent
/data/check1.sh 40 1 1 4096 100.00%
/data/check2.sh 40 1 1 4096 100.00%
/data/check3.sh 40 1 1 4096 100.00%
/data/check4.sh 40 1 1 4096 100.00%
/data/check5.sh 40 1 1 4096 100.00%
/data/check6.sh 40 1 1 4096 100.00%
/data/check7.sh 40 1 1 4096 100.00%
/data/check8.sh 40 1 1 4096 100.00%
/data/check9.sh 40 1 1 4096 100.00%
/data/check10.sh 40 1 1 4096 100.00%
Author: bugwz
Link: https://bugwz.com/2019/01/01/cache-and-buffer/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.