Buffer I/O的数据什么时候刷下去?

Buffer I/O的数据什么时候刷下去?

存储技术最前线 欧美男星 2016-11-08 21:56:58 8

Buffer I/O是解决存储设备性能瓶颈的一个重要手段,当数据量不大的时候,可以将I/O暂时放在内存中;同时,Buffered I/O还会尽可能地merge或者批量刷到磁盘。

Linux为Buffer I/O提供了统一的接口,如文件系统实现的write函数,最终就会调用generic_platform_write将数据提交到Linux Page Cache中。那么数据被Cache后,什么时候刷到磁盘里?


举一个例子,使用dd时,如果不加oflag,则写入的时候是Buffer I/O,通过iotop可以看到有两个进程的I/O占有率比较高,一个是dd,另一个是flush-8:16。这个flush-8:16就是负责刷数据cache操作的,flush-8:16中的8:16以底层设备的major:minor来表示


上面是在centos6.7看到的,从centos7.0开始,这个flush线程就看不见了,而是使用kworker,并通过vmstat调度。这个flush线程的主要工作就是执行bdi_writeback_workfn,它会调用文件系统注册的writepages函数,如下是在xfs上进行Buffer I/O时该线程的stack信息。


该线程在执行通用的函数后(走到do_writepages),会进入xfs注册的writepages函数: xfs_vm_writepages。

因为在调用do_writepages函数时,cache的数据会被刷到存储介质上,文件系统的IO优化都要在这里进行(如xfs的Delayed allocation)。


xfs对cache的数据处理之后,通过submit_bio向block层提交IO 请求,同时注册io结束时的回调函数xfs_end_bio。这时候,IO就进入Linux Block层了。


Block层执行完,xfs_endio_bio会判断bio->bi_flags,如果设置了BIO_UPTODATE(即驱动调用bio_endio时没有设置I/O错误),则正常结束,page会被回收。


如果I/O发生错误,则会在dmesg中打印出"Buffer I/O error on device %s, logical block %Lu\n"和"lost page write due to ""I/O error on %s\n"提示信息。同时将page标志为io error,这里还不太清楚flush线程是否会重新下发这个page。但是可以确定不会引起文件系统不可用。


如果是直接对/dev设备进行Buffer I/O,大致的执行过程也类似,do_writepages中调用blk文件系统的writepages函数(如下图)。

对于Buffer IO的相关信息,可以通过/proc/vmstat查看,下面截取一部分:




总结

从上面的分析可以看到,Linux给文件系统提供了自定义的Buffer I/O落盘接口,各种文件系统可以按照自己的方式落盘。使用Buffer I/O有很多好处,如降低对磁盘的访问率,合并I/O等。但是由于目前一个设备只有一个线程处理落盘任务(还无法控制),对于像NVMe随机读写这种不太合适。如果要充分利用NVMe的随机性能,最好不要使用Buffer I/O。




取消

感谢您的支持鼓励,我会继续努力的!

文章地址:

用户邮箱:

打赏金额:USDT

点击”去打赏“,即可进行打赏支持本文章哦

发表评论