多平台统一管理软件接口,如何实现多平台统一管理软件接口
434
2022-11-04
怎么理解内存中的Buffer和Cache?
一、free数据的来源
Buffer 和 Cache是通过free获取的指标,可以通过man命令查询free的文档,找到对应指标的详细说明,如:执行man free
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
free 手册中,可以看到buffer和cache的说明:
Buffers是内核缓冲区用到的内存,对应是/proc/meminfo中的Buffers值。Cache是内核页缓存和Slab用到的内存,对应是/proc/meminfo中的Cached与SReclaimable之和。
二、proc文件系统
/proc是Linux内核提供的一种特殊文件系统,是用户跟内核交互的接口。比方说,用户可以从/proc中查询内核的运行状态和配置选项,查询进程的运行状态、统计数据等,当然,你也可以通过 /proc 来修改内核的配置。
proc 文件系统同时也是很多性能工具的最终数据来源。比如:free ,就是通过读取/proc/meminfo,得到内存的使用情况。
执行man proc查看proc文件系统的详细文档
Buffers %lu Relatively temporary storage for raw disk blocks that shouldn't get tremendously large (20MB 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的一部分。Slab包括两部分,其中的可回收部分,用SReclaimable记录;而不可回收部分,用SUnreclaim记录。
三、疑问
3.1、疑问一
Buffer的文档没有提到这是磁盘读数据还是写数据的缓存,而在很多网络搜索的结果中都会提到Buffer只是对将要写入磁盘数据的缓存。那么反过来说,它会不会也缓存从磁盘中读取的数据呢?
3.2、疑问二
文档中提到,Cache是对从文件读取数据的缓存,那么它是不是也会缓存写文件的数据呢?
带着两个疑问,运用以下案例展示,Buffer和Cache在不同场景下的使用情况。
四、案例
4.0、环境准备
环境Ubuntu 18.04,其他Linux系统也适用
配置:2CPU、8GB内存预先安装sysstat包
环境准备:为了减少缓存影响,运行下面命令清理系统缓存
# 清理文件页、目录项、Inodes等各种缓存$ echo 3 > /proc/sys/vm/drop_caches
4.1、场景一:文件写案例
终端一:运行vmstat命令
# 每隔1秒输出1组数据$ vmstat 1procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st0 0 0 7743608 1112 92168 0 0 0 0 52 152 0 1 100 0 0 0 0 0 7743608 1112 92168 0 0 0 0 36 92 0 0 100 0 0
输出界面里,内存部分的buff和cache,以及IO部分的bi和bo就是我们要关注的重点。
buff和cache就是前面看到的Buffers和Cache,单位是:KBbi和bo则分别表示块设备读取和写入的大小,单位为块/秒。因为Linux中块的大小是1KB,所以这个单位也就等价于KB/s
备注:正常情况下,空闲系统中,应该看到的是这几个值多次结果中一直保持不变。第二点来自Size是磁盘分区的块大小,是4KB
终端二:执行dd命令,通过读取随机设备,生成一个500MB大小的文件
dd if=/dev/urandom of=/tmp/file bs=1M count=500
返回终端一:观察Buffer和Cache的变化情况
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st0 0 0 7499460 1344 230484 0 0 0 0 29 145 0 0 100 0 0 1 0 0 7338088 1752 390512 0 0 488 0 39 558 0 47 53 0 0 1 0 0 7158872 1752 568800 0 0 0 4 30 376 1 50 49 0 0 1 0 0 6980308 1752 747860 0 0 0 0 24 360 0 50 50 0 0 0 0 0 6977448 1752 752072 0 0 0 0 29 138 0 0 100 0 0 0 0 0 6977440 1760 752080 0 0 0 152 42 212 0 1 99 1 0... 0 1 0 6977216 1768 752104 0 0 4 122880 33 234 0 1 51 49 0 0 1 0 6977440 1768 752108 0 0 0 10240 38 196 0 0 50 50 0
通过观察vmstat输出,发现dd命令运行时,Cache在不断增长,而Buffer基本保持不变。
再进一步观察I/O的情况:
在Cache刚开始增长时,块设备I/O很少,bi只出现了一次488KB/s,bo则只有一次4KB。而过了一段时间后,才会发现大量的块设备写,比如:bo变成了122880当dd命令结束后,Cache不再增长,但块设备写还持续一段时间,并且,多次I/O写的结果加起来,才是dd要写的500M数据
4.2、场景二、磁盘写案例
注意:需要配置多块磁盘,并且磁盘分区 /dev/sdb1 还要处于未使用状态。如果只有一块磁盘,千万不要尝试,否则将会对你的磁盘分区造成损坏。
终端二:清理缓存后,向磁盘分区/dev/sdb1写入2GB的随机数据
# 首先清理缓存$ echo 3 > /proc/sys/vm/drop_caches# 然后运行dd命令向磁盘分区/dev/sdb1写入2G数据$ dd if=/dev/urandom of=/dev/sdb1 bs=1M count=2048
终端二:观察内存和I/O的变化情况
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st1 0 0 7584780 153592 97436 0 0 684 0 31 423 1 48 50 2 0 1 0 0 7418580 315384 101668 0 0 0 0 32 144 0 50 50 0 0 1 0 0 7253664 475844 106208 0 0 0 0 20 137 0 50 50 0 0 1 0 0 7093352 631800 110520 0 0 0 0 23 223 0 50 50 0 0 1 1 0 6930056 790520 114980 0 0 0 12804 23 168 0 50 42 9 0 1 0 0 6757204 949240 119396 0 0 0 183804 24 191 0 53 26 21 0 1 1 0 6591516 1107960 123840 0 0 0 77316 22 232 0 52 16 33 0
可以看到,同样是写数据,写磁盘跟文件的现象还是不同的,写磁盘时(也就是bo大于0时),Buffer和Cache都在增长,但虽然Buffer的增长快得多。
说明,写磁盘用到了大量的Buffer,这跟文档中查询到的定义时一样的。
对比两个案例,我们发现,写文件时会用到 Cache 缓存数据,而写磁盘则会用到 Buffer 来缓存数据。所以,回到场景一的问题,虽然文档上只提到,Cache 是文件读的缓存,但实际上,Cache 也会缓存写文件时的数据。
4.3、场景三:文件读案例
终端二:清理缓存后,从文件 /tmp/file 中,读取数据写入空设备
# 首先清理缓存$ echo 3 > /proc/sys/vm/drop_caches# 运行dd命令读取文件数据$ dd if=/tmp/file of=/dev/null
终端一:观察内存和I/O的变化情况
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 1 0 7724164 2380 110844 0 0 16576 0 62 360 2 2 76 21 0 0 1 0 7691544 2380 143472 0 0 32640 0 46 439 1 3 50 46 0 0 1 0 7658736 2380 176204 0 0 32640 0 54 407 1 4 50 46 0 0 1 0 7626052 2380 208908 0 0 32640 40 44 422 2 2 50 46 0
观察vmstat的输出,会发现读取文件时(也就是bi大于0时),Buffer保持不变,而Cache则在不断增长。
4.4、场景四:磁盘读案例
终端二:运行下面的命令。清理缓存后,从磁盘分区 /dev/sda1 中读取数据,写入空设备
# 首先清理缓存$ echo 3 > /proc/sys/vm/drop_caches# 运行dd命令读取文件$ dd if=/dev/sda1 of=/dev/null bs=1M count=1024
终端一:观察内存和 I/O 的变化情况
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st0 0 0 7225880 2716 608184 0 0 0 0 48 159 0 0 100 0 0 0 1 0 7199420 28644 608228 0 0 25928 0 60 252 0 1 65 35 0 0 1 0 7167092 60900 608312 0 0 32256 0 54 269 0 1 50 49 0 0 1 0 7134416 93572 608376 0 0 32672 0 53 253 0 0 51 49 0 0 1 0 7101484 126320 608480 0 0 32748 0 80 414 0 1 50 49 0
观察 vmstat 的输出,你会发现读磁盘时(也就是 bi 大于 0 时),Buffer 和 Cache 都在增长,但显然 Buffer 的增长快很多。这说明读磁盘时,数据缓存到了 Buffer 中。
经过场景三、四案例的分析,可以对比得出这个结论:读文件时数据会缓存到 Cache 中,而读磁盘时数据会缓存到 Buffer 中。
虽然文档提供了对 Buffer 和 Cache 的说明,但是仍不能覆盖到所有的细节。比如:
Buffer 既可以用作“将要写入磁盘数据的缓存”,也可以用作“从磁盘读取数据的缓存”。Cache 既可以用作“从文件读取数据的页缓存”,也可以用作“写文件的页缓存”。
Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。
五、总结
Buffer 和 Cache 分别缓存磁盘和文件系统的读写数据。
从写的角度来说,不仅可以优化磁盘和文件的写入,对应用程序也有好处,应用程序可以在数据真正落盘前,就返回去做其他工作。从读的角度来说,既可以加速读取那些需要频繁访问的数据,也降低了频繁 I/O 对磁盘的压力。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~