当我们在Linux系统上执行free命令后,会看到buff/cache列。那么这个buffer和cache有什么区别呢。

# free -tm
              total        used        free      shared  buff/cache   available
Mem:           3709        1054        1937          17         718        2404
Swap:          2047           0        2047
Total:         5757        1054        3985

cache(高速缓存)

CPU访问内存速度比访问外部存储器的速度快几个级,Linux内核中采用cache(page cache/高速缓存)来填补这差距。cache主要用来作为文件系统上的文件数据的缓存来用,尤其是针对当进程对文件有read/write操作的时候。

当从外部存储器读取文件X时,首先会被复制至内核内存区域,内核内存区域是所有进程共享的区域。之后再复制到该进程内存区域。

写入时也一样,进程首先会修改进程内存里的内容,之后写入页面缓存,因为比起直接写入外部存储器,写入页面缓存的速度更快。页面缓存中的脏数据将在指定时间内通过后台处理写入外部存储,该指定时间由以下内存参数来决定。

在RedHat Enterprise Linux8.4上确认上面4个参数的结果如下。

内核参数 单位 默认值 备注
vm.dirty_writeback_centisecs 厘秒(1/100秒) 500(5秒) 每5秒进行回写
vm.dirty_background_ratio 百分比(%) 10 当脏页的内存量与搭载内存的比例超过该百分比时
vm.dirty_ratio 百分比(%) 30 超过该指定百分比时,将阻塞进程的写入至页面缓存
vm.dirty_background_bytes 字节数 0 指定字节数,默认0表示禁用

buffer(缓冲区缓存)

buffer的机制与cache的机制相似,系统对块设备进行读写(跳过文件系统,使用设备文件直接访问外部存储器)的时候,对块(block)进行数据缓存的区域。

实验

在进行测试之前使用下面的命令尽量清除系统的页面缓存。不要在生产环境执行该命令,有可能会导致系统抖动。

# echo 3 > /proc/sys/vm/drop_caches

直接写入

创建文件使用dd命令,并且用oflag=direct选项直接写入。执行前后使用free命令查看buff/cache有没有变化。

  1. 使用 echo 3 > /proc/sys/vm/drop_caches 命令清除页面缓存
  2. 使用 free -tm 命令确认结果buff/cache的结果为305MB。
  3. 使用 dd 命令的选项oflag=direct(直接写入的方式),创建1GiB的文件,消耗了1.010秒。
  4. 使用 free -tm 命令确认结果buff/cache的结果为305MB。buff/cache的使用容量几乎没有变化。
  5. 读取 /tmp/demofile 文件,消耗了 0.653秒。
  6. 再次确认 buff/cache 值,增加到了1,333MB。把1GiB的demofile文件的内容复制到了cache。
  7. 再次读取/tmp/demofile,仅消耗了0.173秒。因为demofile已经存在于cache中,所以比第一次读取,快了将近4倍。

使用页面缓存

  1. 使用 echo 3 > /proc/sys/vm/drop_caches 命令清除页面缓存
  2. 使用 free -tm 命令确认结果buff/cache的结果为304MB。
  3. 使用 dd 命令创建1GiB的/tmp/demofile,消耗了1.319秒。比直接写入的时间多了一些,因为首先写入页面缓存,然后从页面缓存写入外部磁盘。
  4. 使用 free -tm 命令确认结果buff/cache的结果为1,329MB。1GiB的/tmp/demofile的内容写入到了页面缓存的结果。
  5. 读取 /tmp/demofile 文件,消耗了 0.146秒。
  6. 再次读取 /tmp/demofile 文件,消耗了 0.171秒。2次读取都是从页面缓存进行读取,所以比从外部磁盘读取快。
  7. 最后使用 free -tm 命令确认 buff/cache结果为1,333MB,几乎没有变化。

小结

离CPU越远读写的成本就越高,目前的内存型数据库也好,Linux的buff/cache机制也好,都是为了降低从外部磁盘进行读写的高成本操作,进而提高系统的性能。