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。