Ext4 文件系统的三种模式(mode)

ext4支持3种DATA模式,用来区分journal的行为

###data = journal
在将data写入文件系统前,必须等待metadata和data的journal已经落盘,性能最差;
当调用fsync时,文件系统的操作包含:fsync(data journal)->fsync(metadata journal)->fsync(data)->fsync(metadata)

###data = ordered
此模式不记录data的journal,只记录metadata的journal,但是在写metadata的journal前必须保证data已经落盘;
当调用fsync时,文件系统的操作包含:fsync(metadata journal)->fsync(data)(确保data先落盘)->fsync(metadata)

###data = writeback
不记录data journal,仅记录metadata journal,并且可以不保证data比metadata先落盘;
当调用fsync时,文件系统的操作包含:fsync(metadata journal)->fsync(metadata)

metadata的操作在单个ext4文件系统中是串行的,所以某个用户的metadata操作堵塞的话,会影响所有人操作同一个文件系统的metadata,即使writeback模式下也是如此;

###系统缓存相关的几个内核参数介绍

/proc/sys/vm/dirty_background_ratio

该文件表示脏数据到达系统整体的内存的百分比,此时触发pdflush进程把脏数据写回磁盘;当用户调用write时,如果发现系统中的脏数据大于这个阈值(或dirty_background_bytes),会触发pdflush进程去写脏数据,但是用户的write调用会立即返回,无需等待。pdfl刷脏页的标准是让脏页降低到该阈值以下;

/proc/sys/vm/dirty_expire_centisecs

该文件表示如果脏数据在内存中驻留的时间超过该值,pdflush进程在下一次将把这些数据写回磁盘;

/proc/sys/vm/dirty_ratio

该文件表示如果进程产生的脏数据到达系统整体内存的百分比,此时用户进程自行把脏数据写回磁盘;当用户调用write时,如果发现系统中的脏数据大于这个阈值(或dirty_bytes),需要自己把脏数据刷回磁盘,降低到这个阈值以下才会返回;

/proc/sys/vm/dirty_writeback_centisecs

该文件表示pdflush进程的唤醒间隔,周期性把超过dirty_expire_centisecs时间的脏数据写回磁盘;

###系统一般在下面三种情况下回写dirty页
1)定时方式:定时回写是基于这样的原则:/proc/sys/vm/dirty_writeback_centisecs的值表示多长时间会启动回写线程,由这个定时器启动的回写线程只回写在内存中为dirty时间超过(/proc/sys/vm/dirty_expire_centisecs / 100)秒的页(这个值默认是3000,也就是30秒),一般情况下dirty_writeback_centisecs的值是500,也就是5秒,所以默认情况下系统会5秒钟启动一次回写线程,把dirty时间超过30秒的页回写,要注意的是,这种方式启动的回写线程只回写超时的dirty页,不会回写没超时的dirty页,可以通过修改/proc中的这两个值,细节查看内核函数wb_kupdate。
2)内存不足的时候: 这时并不将所有的dirty页写到磁盘,而是每次写大概1024个页面,直到空闲页面满足需求为止。
3) 写操作时发现脏页超过一定比例:当脏页占系统内存的比例超过/proc/sys/vm/dirty_background_ratio 的时候,write系统调用会唤醒pdflush回写dirty page,直到脏页比例低于/proc/sys/vm/dirty_background_ratio,但write系统调用不会被阻塞,立即返回。当脏页占系统内存的比例超/proc/sys/vm/dirty_ratio的时候, write系统调用会被被阻塞,主动回写dirty page,直到脏页比例低于/proc/sys/vm/dirty_ratio。

###[参考]
https://yq.aliyun.com/articles/15241#