缓存的概念
这里讲的buffer和cache是内存中的概念,buffer和cache是常见的内存指标。通过free命令可以看出来buffer/cache的大小
# free -m
total used free shared buff/cache available
Mem: 1819 187 1201 9 430 1417
Swap: 2047 0 2047
其中的缓存指的就是buffer和cache。通过man free 命令可以看到
buffers
Memory used by kernel buffers (Buffers in /proc/meminfo)
cache
Memory used by the page cache and slabs (Cached and Slab in /proc/meminfo)
buff/cache
Sum of buffers and cache
available
Estimation of how much memory is available for starting new applications, without swapping. Unlike the data provided by the
cache or free fields, this field takes into account page cache and also that not all reclaimable memory slabs will be
reclaimed due to items being in use (MemAvailable in /proc/meminfo, available on kernels 3.14, emulated on kernels 2.6.27+,
otherwise the same as free)
这里的解释是 buffer是内核缓冲区用到的内存,cache是页缓存和slab用到的内存。
而最后的available是预计还有多少内存可以用来启动新的程序,而无需交换。不同于cache和free字段,此字段考虑页面缓存,并且不是所有可回收的内存都会被回收。
这里就得到大致的概念。
- buffer 这是对原始磁盘块的临时存储,用来缓存磁盘数据,通常不会太大,将内核中分散的数据读写集中起来。
- cache 这是从磁盘读取文件的页缓存,缓存文件中的读写数据,这样下次就可以从内存中快速读取数据。
在centos等内核版本较低的执行dstat
# dstat --mem
------memory-usage-----
used buff cach free
297M 2108k 496M 1024M
297M 2108k 496M 1024M
在ubuntu等内核版本较高的可以执行adv显示更加详细的内容。这里多了dirty脏页(未落盘的数据)。shmem共享内存。recl这个是slab的一部分,而recl是指的SReclaimable记录,是属于可回收部分。
$ dstat --mem-adv
-------------advanced-memory-usage-------------
total used free buff cach dirty shmem recl
7905M 3946M 253M 37.3M 5838M 55.5M 2313M 144M
7905M 3950M 249M 37.3M 5842M 55.7M 2317M 144M
实验
首先先清除掉系统上的文件页,目录项,Inodes等各种缓存。
# dstat --mem
------memory-usage-----
used buff cach free
297M 2108k 496M 1024M
# echo 3 > /proc/sys/vm/drop_caches
# dstat --mem
------memory-usage-----
used buff cach free
272M 0 75.6M 1472M
写入数据(文件)
使用 dd 命令大量写入文件。看看buffer和cache的变化。
# dd if=/dev/urandom of=/tmp/file bs=10M count=500
通过vmstat观察
# 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 1506792 0 172320 0 0 0 0 168 307 0 0 100 0 0
1 0 0 1486428 0 182684 0 0 96 0 296 382 0 2 98 0 0
1 0 0 1360352 0 308796 0 0 0 2 596 445 0 12 88 0 0
1 0 0 1234544 0 435080 0 0 9 159744 1075 261 0 21 79 0 0
1 0 0 1098208 0 571324 0 0 0 106496 967 209 0 20 80 0 0
2 0 0 962896 0 706820 0 0 0 113152 1532 758 0 26 74 0 0
1 0 0 844528 0 825080 0 0 0 153088 1438 479 0 28 72 0 0
1 0 0 740312 0 929308 0 0 0 106496 1588 313 0 29 71 0 0
1 0 0 664976 0 1004528 0 0 0 155444 1810 841 0 28 72 0 0
1 0 0 592900 0 1076612 0 0 0 0 1008 367 0 23 77 0 0
由上面的vmstat观察得出。在写入大量文件后,cache不停的增长,随后 bo(块设备写入)变大。buffer就没变。
得出结论。
- 在Cache增长的时候,块设备的I/O很少,cache增长几秒后才开始有bo的增长。
- dd命令结束后,Cache不再增长,块设备写入还会持续一段时间,并且,多次I/O写的结果加起来才是dd要写的5G的数据。
读取数据(文件)
再次清空缓存,读取数据试试呢。
# echo 3 > /proc/sys/vm/drop_caches
读取文件的数据
# dd if=/tmp/file of=/dev/null
使用vmstat观察,这里的bi(块设备的读入)增长。随之cache也发生增长,而buffer并没有改变。
# 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 1032 1536504 0 140596 0 0 0 0 196 348 0 1 100 0 0
0 0 1032 1536504 0 140596 0 0 48 49 194 339 0 0 100 0 0
0 0 1032 1536504 0 140596 0 0 0 0 152 290 0 0 100 0 0
1 0 1032 1512200 0 165084 0 0 24476 0 259 391 0 1 93 6 0
0 1 1032 1450756 0 226560 0 0 61440 0 308 425 0 2 78 20 0
0 1 1032 1393404 0 283856 0 0 57344 4 302 411 0 1 78 21 0
0 1 1032 1323788 0 353512 0 0 69632 0 321 462 0 2 79 19 0
0 1 1032 1266684 0 410696 0 0 57344 0 330 442 0 2 78 20 0
0 1 1032 1197080 0 480472 0 0 69632 0 321 472 0 2 78 20 0
这里其实就已经知道了,其实cache就是对文件写入读入的缓存
读取数据(磁盘块设备)
同样清空缓存再执行dd命令读取块设备。
# echo 3 > /proc/sys/vm/drop_caches
# dd if=/dev/sda1 of=/dev/null bs=1M count=500
再通过vmstat去观察缓存的变化。这里终于看到了buffer的变化。
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
0 0 1032 1542340 0 134788 0 0 0 0 171 311 0 0 100 0 0
0 0 1032 1542340 0 134788 0 0 0 0 149 283 0 0 100 0 0
1 0 1032 1542308 0 134804 0 0 76 0 252 422 1 0 99 0 0
0 1 1032 1449288 92160 134864 0 0 92160 0 361 508 0 2 76 22 0
0 0 1032 1023856 518144 135056 0 0 426192 87 1262 352 0 7 86 7 0
1 0 1032 1023856 518144 135056 0 0 0 16 135 323 0 0 100 0 0
0 0 1032 1023856 518144 135056 0 0 0 0 128 294 0 0 100 0 0
观察得出,在读块设备时,buffer和cache都出现了增长,但是明显buffer的变化更大。这里就不再实验对磁盘块设备的数据读取。
小结
buffer 是 磁盘的数据的缓存。读和写都会缓存
cache 是 文件的数据的缓存。读和写都会缓存