Linux 内存 Buffer 和 Cache

Aug 1, 2020 00:00 · 1746 words · 4 minute read Linux

从字面上讲,Buffer 是缓冲区而 Cache 是缓存,两者都是数据在内存中的临时存储,那两者到底有什么区别呢?

我们都知道通过 free 命令可以来查看系统的内存使用情况:

$ free
              total        used        free      shared  buff/cache   available
Mem:        1877360      384856     1159340        9880      333164     1332196
Swap:       2097148           0     2097148

其中第 5 列缓存被定义为 Buffer 和 Cache 两者之和,通过 man free 查询相关文档并找到 Buffer 和 Cache 的定义:

$ man free
DESCRIPTION
       buffers
              Memory used by kernel buffers (Buffers in /proc/meminfo)

       cache  Memory used by the page cache and slabs (Cached and SReclaimable in /proc/meminfo)

       buff/cache
              Sum of buffers and cache
  • Buffer 是内核缓冲区使用的内存,真正的数据来源是 /proc/meminfo 文件中的 Buffers 值。
  • Cache 是内核页缓存与 Slab 用到的内存,真正的数据来源是 /proc/meminfo 文件中 Cached 与 SReclaimable 两者之和。

我们跟随文档去查看一下 /proc/meminfo 文件:

/proc 是目录也是“文件系统”,用户可以通过 /proc 来查看内核的运行状态和配置,也可以通过 /proc 来修改内核配置。

$ cat /proc/meminfo
Buffers:            5216 kB
Cached:           289388 kB
SReclaimable:      38572 kB
SUnreclaim:        44428 kB

/proc 相关文档 https://linux.die.net/man/5/proc 对 Buffers、Cached 和 SReclaimable 几个指标的详细说明:

  • Buffers %lu Relatively temporary storage for raw disk blocks that shouldn’t get tremendously large (20 MB or so).

  • Cached %lu In-memory cache for files read from the disk (the page cache). Doesn’t include SwapCached.

  • SReclaimable %lu (since Linux 2.6.19) Part of Slab, that might be reclaimed, such as caches.

  • SUnreclaim %lu (since Linux 2.6.19) Part of Slab, that cannot be reclaimed on memory pressure.

  • Buffers 是对原始磁盘块的临时存储,通常不大(20MB 左右)

  • Cached 是从磁盘读取文件的缓存

  • SReclaimable 是 Slab 的一部分,可回收

  • SUnreclaim 是 Slab 的另一部分,不可回收

Cache

首先清理系统缓存 echo 3 > /proc/sys/vm/drop_caches,然后使用 dd 命令读取随机设备生成一个 500MB 的文件,同时使用 vmstat 观察:

$ dd if=/dev/urandom of=/tmp/file bs=1M count=500
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 2.72693 s, 192 MB/s
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 1366472      0 143956    0    0    84     0  234  148  0  4 96  0  0
 1  0      0 1160568      0 349680    0    0     0 106496 1604  577  1 51 49  0  0
 1  0      0 971608      0 538328    0    0     0 159744 1644  542  0 51 49  0  0
 0  0      0 852328      0 658652    0    0     0 167936 1386  484  0 35 65  0  0
 0  0      0 852444      0 658652    0    0     0     0   92  103  1  0 99  0  0
 0  0      0 852400      0 658652    0    0     0     0   72   78  1  1 99  0  0

随着 /tmp/file 文件生成,Buffer 一直都是 0 而 Cache 在不断增大。开始的时候块设备 I/O (bi/bo)很少,过一段时间后 block out 急剧增大,

清理系统缓存后读回刚才生成的文件 /tmp/file,同时使用 vmstat 观察:

$ dd if=/tmp/file of=/dev/null
1024000+0 records in
1024000+0 records out
524288000 bytes (524 MB) copied, 1.36646 s, 384 MB/s
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 1408820      0 118816    0    0     0     0   93  102  1  1 99  0  0
 0  0      0 1409036      0 118816    0    0     0     0   71   74  0  0 99  0  0
 1  0      0 1274084      0 253884    0    0 135088     0  411  160  6  9 84  2  0
 1  0      0 905512      0 622460    0    0 368640     0 1031  260 17 27 50  7  0
 0  0      0 897540      0 630912    0    0  8368     0  151  107  2  2 97  0  0
 0  0      0 897684      0 630912    0    0     0     0   68   75  0  0 99  0  0

与写文件时相同 Buffer 一直都是 0 而 Cache 在不断增大。

接下来我们使用 ll 命令查看 $HOME 目录,同时使用 vmstat 观察:

$ ll
total 8
-rw-------. 1 root root 1834 Aug 10  2017 anaconda-ks.cfg
-rw-r--r--. 1 root root 1862 Aug 10  2017 initial-setup-ks.cfg
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 1401088      0 118280    0    0   128     0  111  109  0  0 99  0  0
 0  0      0 1400952      0 118284    0    0     0     0   73   78  0  0 99  0  0
 0  0      0 1401036      0 118284    0    0     0     0   76   79  0  1 99  0  0

Cache 与“文件”,也就是经过操作系统处理后的数据相关。

Buffer

同样先清理系统缓存 echo 3 > /proc/sys/vm/drop_caches,然后向磁盘 /dev/sdb 写入 2GB 随机数据,同时使用 vmstat 观察:

$ dd if=/dev/urandom of=/dev/sdb bs=1M count=2048
2048+0 records in
2048+0 records out
2147483648 bytes (2.1 GB) copied, 11.4353 s, 188 MB/s
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 1394500      0 119772    0    0  2504     0  513  613  2  1 97  1  0
 0  0      0 1394368      0 119772    0    0     0     0  163  159  0  1 99  0  0
 0  0      0 1394448      0 119772    0    0     0     0  155  159  1  0 99  0  0
 1  0      0 1307768  83968 121872    0    0   208     0  911  560  1 22 78  1  0
 1  0      0 1114032 272384 126764    0    0     0 172032 1668  364  1 53 46  0  0
 1  0      0 912456 468992 131800    0    0     0 172032 1507  293  1 52 48  0  0
 1  0      0 707644 668672 136876    0    0     0 229376 2010  659  0 53 47  0  0
 1  0      0 499448 871424 142456    0    0    12 172032 2283  904  1 52 46  0  0
 2  0      0 292924 1072128 148096    0    0     0 229376 1512  250  1 52 47  0  0
 1  0      0  85604 1273856 153772    0    0     0 192512 1422  203  0 52 49  0  0
 2  1      0  72692 1290028 149824    0    0  7216 172032 1786  427  1 53 44  3  0
 1  0      0  71740 1291508 150340    0    0     0 229376 1477  248  1 53 47  0  0
 1  0      0  72060 1290620 150792    0    0     0 172032 1425  246  1 52 48  0  0
 1  0      0  66276 1295964 151380    0    0     0 172032 2152  734  0 53 47  0  0
 0  0      0 1397456      0 115596    0    0  1272 184320 1134  575  1 24 72  5  0
 0  0      0 1397332      0 115596    0    0     0     0   79   85  0  1 100  0  0

在写磁盘的过程中 Buffer 与 Cache 都在上涨但 Buffer 的增长速度比 Cache 快得多。

同样清理缓存后直接从磁盘读取数据,同时使用 vmstat 观察:

$ dd if=/dev/sdb of=/dev/null bs=1M count=2048
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 1401260      0 119252    0    0     0     0   70   73  0  0 99  0  0
 0  0      0 1401160      0 119252    0    0     0     0   82   82  0  1 100  0  0
 0  1      0 1099480 301056 119388    0    0 301132     0  334  257  1  5 59 35  0
 0  1      0 644548 755712 119632    0    0 454656     0  350  303  0  7 51 42  0
 0  1      0 188676 1210368 120520    0    0 454656     0  396  296  1  8 49 42  0
 0  1      0  66832 1338336 114680    0    0 449456     0  726  467  0 11 46 43  0
 2  0      0  66812 1337468 115700    0    0 450560     0  551  380  1 10 47 42  0
 0  0      0 1408048      0 112540    0    0    32     0  269  205  1  6 94  0  0
 0  0      0 1408048      0 112540    0    0     0     0   71   76  0  1 100  0  0

与写磁盘相同 Buffer 与 Cache 都在增长但 Buffer 的增长速度比 Cache 快得多。

Buffer 与“块设备”也就是原始磁盘数据相关。