free
命令中会有一项buff/cache
,
通过man free
可以看到这里的关于buff/cache
的介绍
buff/cache
包含两部分
buffers
:内核缓存区用到的内存,对应/proc/meminfo
中Buffers
的值
cache
:内核页缓存和Slab
用到的内存,对应/proc/meminfo
中Cached
与SReclaimable
之和。
执行man proc
可以看到关于/proc/meminfo
的说明。
Buffers
是对原始磁盘块的临时缓存,通常不会特别大(20M左右)。
Cached
是从磁盘读取文件的页缓存
SReclaimable
是Slab
的一部分。
Slab
包括两部分,其中的可回收部分,用SReclaimable
记录,而不可回收的部分,用SUnreclaim
表示。
基于Ubuntu 20.04.1 LTS
执行apt install sysstat
,安装sysstat
包。
执行echo 3 >/proc/sys/vm/drop_caches
清空系统缓存。
写入
/proc/sys/vm/drop_caches
表示清理文件页,目录项,Inodes
等各种缓存。
执行vmstat 1
每1秒输出1组数据。
buff
和 cache
就是我们前面看到的 Buffers
和 Cache
,单位是 KB
。
bi
和 bo
则分别表示块设备读取和写入的大小,单位为块 / 秒。因为 Linux
中块的大小是 1KB
,所以这个单位也就等价于 KB/s
。
新开一个shell
窗口,执行 dd if=/dev/urandom of=/tmp/file bs=1M count=500
,通过读取随机设备,生成一个 500MB 大小的文件。
回到vmstat
的窗口,会看到在 dd
命令运行时, Cache
在不停地增长,而 Buffer
基本保持不变。
可以看到cache
刚开始增长,块设备 I/O 很少。而过一段时间后,才会出现大量的块设备写。
由于
dd
命令写出512000KB,所以bo
的大小至少会等于512000KB,有可能会大于这个值,这是由于系统中其他进程也会写文件,比如第一行的bo
的380。多次执行的话,就会看到
dd
命令对应的bo
的值就是512000KB。这里也可以看到
cache
先增长,后面才会有bo
增长。这是由于先写入cache
缓存, 此时不会和磁盘进行交互, 当需要将缓存数据刷入磁盘时, 才会发生块写入此时bo
值会升高
echo 3 > /proc/sys/vm/drop_caches
dd if=/dev/urandom of=/dev/sdb1 bs=1M count=2048 #注意:这个是直接写到磁盘上,会导致历史数据全部丢失。建议找一个空盘测试
再次观察vmstat
的记录,可以看到buff
和 cache
都在增长,但显然 buff
的增长快得多。
这里的结果和man
命令的说明是一致的。写文件时会用到 Cache
缓存数据,而写磁盘则会用到 Buffer
来缓存数据。
刚才是文件和磁盘读取时候buff
和cache
的变化,现在我们再看看写操作的情况。
执行下面的命令。
# 首先清理缓存
echo 3 > /proc/sys/vm/drop_caches
# 运行dd命令读取文件数据
dd if=/tmp/file of=/dev/null
再次观察vmstat
的记录
就可以看到这次还是cache
有明显的增长,也就是我们读取内存的大小(512000KB
),不过这次由于我们是读取,所以bi
有明显的增长也会是512000KB。
上面是读取文件,我们再看看读取磁盘。
执行下面给的命令
# 首先清理缓存
echo 3 > /proc/sys/vm/drop_caches
# 运行dd命令读取文件
dd if=/dev/sda1 of=/dev/null bs=1M count=1024
可以看到,buff
和bi
有明显的增长。也就是我们读取内容的大小1024000KB
。
从上面也可以看到:
Buffer
: 如果没有经过文件系统,直接从磁盘读取、写入数据,就会体现到Buffer
中。既可以用作“将要写入磁盘数据的缓存”,也可以用作“从磁盘读取数据的缓存”。
Cache
:如果经过文件系统,从磁盘读取、写入数据,就会体现到Cache
中。既可以用作“从文件读取数据的页缓存”,也可以用作“写文件的页缓存”。