Linux 内存 Buffer 和 Cache
Aug 1, 2020 00:00 · 1746 words · 4 minute read
从字面上讲,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 与“块设备”也就是原始磁盘数据相关。