当我们在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有没有变化。
- 使用 echo 3 > /proc/sys/vm/drop_caches 命令清除页面缓存
- 使用 free -tm 命令确认结果buff/cache的结果为305MB。
- 使用 dd 命令的选项oflag=direct(直接写入的方式),创建1GiB的文件,消耗了1.010秒。
- 使用 free -tm 命令确认结果buff/cache的结果为305MB。buff/cache的使用容量几乎没有变化。
- 读取 /tmp/demofile 文件,消耗了 0.653秒。
- 再次确认 buff/cache 值,增加到了1,333MB。把1GiB的demofile文件的内容复制到了cache。
- 再次读取/tmp/demofile,仅消耗了0.173秒。因为demofile已经存在于cache中,所以比第一次读取,快了将近4倍。
使用页面缓存
- 使用 echo 3 > /proc/sys/vm/drop_caches 命令清除页面缓存
- 使用 free -tm 命令确认结果buff/cache的结果为304MB。
- 使用 dd 命令创建1GiB的/tmp/demofile,消耗了1.319秒。比直接写入的时间多了一些,因为首先写入页面缓存,然后从页面缓存写入外部磁盘。
- 使用 free -tm 命令确认结果buff/cache的结果为1,329MB。1GiB的/tmp/demofile的内容写入到了页面缓存的结果。
- 读取 /tmp/demofile 文件,消耗了 0.146秒。
- 再次读取 /tmp/demofile 文件,消耗了 0.171秒。2次读取都是从页面缓存进行读取,所以比从外部磁盘读取快。
- 最后使用 free -tm 命令确认 buff/cache结果为1,333MB,几乎没有变化。
小结
离CPU越远读写的成本就越高,目前的内存型数据库也好,Linux的buff/cache机制也好,都是为了降低从外部磁盘进行读写的高成本操作,进而提高系统的性能。