粗谈Linux中buffer和cache的使用场景

1. 小声哔哔

    既然你已经看到这篇博文,说明你已经对buffer和cache已经产生了疑惑,为什么我的机器内存分配了一块内存给buffer/cache,这部分内存究竟是如何产生的,在内存紧张时我该怎么释放它。下面我基于自己的运维经验和倪朋飞老师的《Linux性能优化实战》探讨一下Buffer/Cache。

2. 前菜小点

    工欲善其事必先利其器,能够查看内存中buffer/cache使用量的工具有很多,比如free,vmstat,sar -r。此时需要你手中有一台虚拟机,尝试执行以上三个命令,你会发现其中free结果显示中将buffer和cache混在了一起,显然不是我们想要的。对比vmstat和sar -r的结果发现vmstat中的cache结果值居然比sar -r的大,那么问题来了,哪个是对的。这时可以新建一个会话,执行watch cat /proc/meminfo,你会发现vmstat中的cache是meminfo中的Cached和SReclaimable之和,而sar -r中的cache值与meminfo中的Cached相等。

   执行man proc查看一下Linux proc文件系统的详细文档,其中对Buffers、Cached、SReclaimable的定义如下。

    Buffers 是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB 左右)。这样,内核就可以把分散的写集中起来,统一优化磁盘的写入,比如可以把多次小的写合并成单次大的写等等。

    Cached 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据(不包括SwapCached)。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。

    SReclaimable 是 Slab 的一部分。Slab 包括两部分,其中的可回收部分,用 SReclaimable 记录;而不可回收部分,用 SUnreclaim 记录。

    之前觉得既然sar -r命令和watch cat /proc/meminfo更为准确,但是碰到的案例多了以后就会发现,buffer和cache增加往往伴随着磁盘或者文件读写,此时用vmstat来查看系统情况更合适,因为vmstat中还可以查看块设备的读写情况。

3. 正餐开始

    在前菜中通过man proc查看了文件系统中对buffer和cache的定义,那么是不是简单的这么理解就可以呢。下面我们进入正餐。

    首选,准备一个虚拟机,我这边准备的是一个1U2G的虚拟机,下面的实践步骤参考了倪朋飞老师的《Linux性能优化实战》中第16讲的案例。我们使用dd命令来模拟磁盘及文件的读写,在执行前为了减少当前系统已有缓存的影响,我们执行以下命令来清除缓存:

# 清理文件页、目录项、Inodes等各种缓存
echo 3 > /proc/sys/vm/drop_caches

    下面我们分4个场景进行验证,观察cache和buffer的变化情况:

3.1. 场景一:写文件

    首先打开两个会话框,在第一个会话框执行vmstat 1,每一秒查看一次系统数据

    然后在第二个对话框我们使用dd命令构造场景。通过读取随机设备,生成一个500M大小的文件:

dd if=/dev/urandom of=/tmp/file bs=1M count=500

    vmstat的bi代表块设备的每秒读取量(读磁盘),bo代表块设备每秒写入数量(写磁盘),默认块大小是1K。

    观察左边窗口vmstat的执行结果,注意观察红框中的内容,因为不方便上传动图建议实际在虚拟机执行一下,可以发现以下两个现象:

  • 在第一个红框的阶段,dd命令执行之初,cache开始增长,但是观察发现块设备I/O并没有明显增长,过了一段时间以后bo才开始增长。
  • 在第二个红框的阶段,dd命令执行完成后,cache不再增长,但是块设备I/O还在增加

    看到这里就会发现一个奇怪的现象,为什么明明上面说的cache是文件读缓存,现在文件写为什么cache也开始有明显增长。先不着急,最后我们将四个场景都实验完成再分析。

3.2. 场景二:读文件

    首先防止场景一的实验影响本场景系统数据,首先执行以下命令清除缓存:

echo 3 > /proc/sys/vm/drop_caches

    然后老规矩,开两个窗口,第一个窗口执行vmstat 1,用于观察cache/buffer和块设备情况。第二个窗口执行: dd if=/tmp/file of=/dev/null 读取文件数据。注意,这里的/tmp/file是我们做场景一实验的时候产生的,做场景二实验之前别给删除了。执行结果如下   

    可以看出,在读文件时,buffer没有增长,但是cache在不停的增长,这个与我们查看到的定义是一致的。

3.3. 场景三:写磁盘

    注意:本场景写的目标磁盘需要是一个空盘,这里建议使用lsblk查看一下磁盘分区,如果是本机的虚拟机,建议新挂一块磁盘用于测试,如果不具备条件的建议就不要尝试了。

# 首先防止之前的命令影响本场景系统数据,首先执行以下命令清除缓存:
echo 3 > /proc/sys/vm/drop_caches
# 然后运行dd命令向磁盘分区/dev/sda3写入512M数据
dd if=/dev/urandom of=/dev/sda3 bs=1M count=512

    观察截图中的左侧会话,可以发现在写磁盘时,虽然buffer和cache都在增长,但是明显buffer的增长幅度更大。这与我们之前查到的buffer在写磁盘中起作用相符。

3.4. 场景四:磁盘读

# 首先防止之前的命令影响本场景系统数据,首先执行以下命令清除缓存:
echo 3 > /proc/sys/vm/drop_caches
# 然后执行命令读取磁盘中数据:
dd if=/dev/sda3 of=/dev/null bs=1M count=512

    观察左边的会话,发现在bi大于0时(读磁盘)buffer和cache都有增长,但是明显还能看出buffer的增长还是比cache明显的。

4. 总结    

    经过以上4个场景的尝试,大家应该就能发现buffer和cache的使用场景并不是像我们在前菜中理解的那样,基于实践结果我们可以总结出来buffer是对磁盘读写的缓存,cache是对文件读写的缓存。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值