Linux cache 介绍及控制

文章目录

有关 Cache

文件缓存是提升性能的重要手段。毋庸置疑,读缓存(Read caching)在绝大多数情况下是有益无害的(程序可以直接从 RAM 中读取数据),而写缓存(Write caching)则相对复杂。Linux 内核将写磁盘的操作分解成了,先写缓存,每隔一段时间再异步地将缓存写入磁盘。这提升了 IO 读写的速度,但存在一定风险。数据没有及时写入磁盘,所以存在数据丢失的风险。

同样,也存在 cache 被写爆的情况。还可能出现一次性往磁盘写入过多数据,以致使系统卡顿。之所以卡顿,是因为系统认为,缓存太大用异步的方式来不及把它们都写进磁盘,于是切换到同步的方式写入。(异步,即写入的同时进程能正常运行;同步,即写完之前其他进程不能工作)。

好消息是,你可以根据实际情况,对写缓存进行配置。
可以看一下这些参数:

[root@host ~]# sysctl -a | grep dirty
vm.dirty_background_ratio = 10
vm.dirty_background_bytes = 0
vm.dirty_ratio = 20
vm.dirty_bytes = 0
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000

vm.dirty_background_ratio是内存可以填充“脏数据”的百分比。这些“脏数据”在稍后是会写入磁盘的,pdflush/flush/kdmflush 这些后台进程会稍后清理脏数据。举一个例子,我有 32G 内存,那么有 3.2G 的内存可以待着内存里,超过 3.2G 的话就会有后来进程来清理它。

vm.dirty_ratio是绝对的脏数据限制,内存里的脏数据百分比不能超过这个值。如果脏数据超过这个数量,新的 IO 请求将会被阻挡,直到脏数据被写进磁盘。这是造成 IO 卡顿的重要原因,但这也是保证内存中不会存在过量脏数据的保护机制。

vm.dirty_expire_centisecs指定脏数据能存活的时间。在这里它的值是 30 秒。当 pdflush/flush/kdmflush 进行起来时,它会检查是否有数据超过这个时限,如果有则会把它异步地写到磁盘中。毕竟数据在内存里待太久也会有丢失风险。

vm.dirty_writeback_centisecs指定多长时间 pdflush/flush/kdmflush 这些进程会起来一次。

可以通过下面方式看内存中有多少脏数据:

[root@host ~]# cat /proc/vmstat | egrep "dirty|writeback"
nr_dirty 69
nr_writeback 0
nr_writeback_temp 0

这说明了,我有 69 页的脏数据要写到磁盘里。


情景 1:减少 Cache

你可以针对要做的事情,来制定一个合适的值。
在一些情况下,我们有快速的磁盘子系统,它们有自带的带备用电池的 NVRAM caches,这时候把数据放在操作系统层面就显得相对高风险了。所以我们希望系统更及时地往磁盘写数据。
可以在/etc/sysctl.conf 中加入下面两行,并执行”sysctl -p”

vm.dirty_background_ratio = 5
vm.dirty_ratio = 10

这是虚拟机的典型应用。不建议将它设置成 0,毕竟有点后台 IO 可以提升一些程序的性能。


情景 2:增加 Cache

在一些场景中增加 Cache 是有好处的。例如,数据不重要丢了也没关系,而且有程序重复地读写一个文件。允许更多的 cache,你可以更多地在内存上进行读写,提高速度。

vm.dirty_background_ratio = 50
vm.dirty_ratio = 80

有时候还会提高 vm.dirty_expire_centisecs 这个参数的值,来允许脏数据更长时间地停留。


情景 3:增减兼有

有时候系统需要应对突如其来的高峰数据,它可能会拖慢磁盘。(比如说,每个小时开始时进行的批量操作等)
这个时候需要容许更多的脏数据存到内存,让后台进程慢慢地通过异步方式将数据写到磁盘当中。

vm.dirty_background_ratio = 5
vm.dirty_ratio = 80

这个时候,后台进行在脏数据达到 5%时就开始异步清理,但在 80%之前系统不会强制同步写磁盘。这样可以使 IO 变得更加平滑。


从/proc/vmstat, /proc/meminfo, /proc/sys/vm 中可以获得更多资讯来作出调整。

参考文档

https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/