Linux I/O系列之直接内存(Direct IO)原理剖析和使用
系列文章
Linux I/O操作fsync后数据就安全了么(fsync、fwrite、fflush、mmap、write barriers详解)
Linux I/O系列之直接内存(Direct IO)原理剖析和使用
Linux I/O系列:不使用fsync如何尽快将数据写入磁盘(posix_fadivce的作用与实际应用)
一、前言
在上一篇文章《Linux I/O操作fsync后数据就安全了么(fsync、fwrite、fflush、mmap、write barriers详解)》中咱们一起学习了在Linux中如何将数据安全的写入到磁盘。其中我们提到了直接IO。使用它能够在磁盘缓存空间和用户空间直接建立一个通道,这样咱们在用户空间就能够直接操作磁盘中的数据。
本文咱们就一起深入学习直接IO,在开始之前大家可以先思考下面几个问题,看看自己是否都能够正确解答。
1、什么是直接IO?
2、什么场景下可以使用直接IO?
3、为什么我们需要使用直接IO?
4、直接IO的优缺点是什么?
5、直接IO中,应用Buffer和磁盘之间到底有没有缓存?
二、直接IO
1、什么是直接IO
直白点的解释:直接IO就是在应用层Buffer和磁盘之间直接建立通道。这样在读写数据的时候就能够减少上下文切换次数,同时也能够减少数据拷贝次数,从而提高效率。
官方解释如下:主要关注如下两点,
a、在应用层和磁盘之间的通道并不是没有缓存,只是缓存很小。
b、直接IO并不能保证O_SYNC特性。
2、如何使用直接IO
直接IO的使用很简单,只需要在open文件的时候添加O_DIRECT标识即可。但是咱们的Java本身并不支持直接IO。如果Java程序想要使用直接IO则需要引用JNA包,通过直接调用Linux底层指令来操作文件,在打开文件(open)的时候自己指定O_DIRECT标识。直接IO在Ignite中使用的比较好,大家可以参考他的具体代码示例使用例子(搜索ignite官方下载代码即可)。具体代码在ignite-direct-io包中。
3、使用直接IO的注意事项
通常直接IO的使用都会导致性能下降。因为数据几乎没有被内核缓存,所有的读写操作都是直接对磁盘中的文件进行操作。所以使用的时候需要在应用层做好缓存,合理进行读写操作,否则会导致性能急剧下降。
另外使用直接IO需要基于块的维度读写数据,即数据的读写需要是设备的块大小和linux系统的页大小的整数倍。所以通常我们都以4K大小的块读写数据。
4、直接IO的优缺点
A、优点
a、应用层直接操作磁盘减少了上下文切换和数据拷贝的开销,速度更快。
b、数据直接缓存在应用层,应用能够更加灵活的操作数据。
B、缺点
a、系统基本不缓存数据,因此应用需要合理的读写数据,否则会导致性能很差。
b、所有缓存都由应用层直接控制,增加了应用层的实现复杂度,对开发者能力要求很高。
c、O_DIRECT也不能确保数据每次写入的时候同步写入磁盘,因此如果需要数据同步写入磁盘还需要手工设置O_SYNC标识或者手工调用fsync方法。
5、问题解答
对直接IO的学习就到这里,最后我们来一一解答之前咱们提出的问题。
1、什么是直接IO?
正文已解答。
2、什么场景下可以使用直接IO?
通常需要自己控制所有数据的缓存,想要更加灵活自如的输出文件数据。如数据库、同步日志系统等。
3、为什么我们需要使用直接IO?
参考其优点。
4、直接IO的优缺点是什么?
正文已解答。
5、直接IO中,应用Buffer和磁盘之间到底有没有缓存?
有缓存,只是很小。
最后给大家留一个问题:既然直接IO在引用Buffer和磁盘之间有缓存,那这个缓存在哪个位置呢?C标准库Buffer?内核的Page Cache?
三、惯例
如果你喜欢本文或觉得本文对你有所帮助,欢迎一键三连支持,非常感谢。
如果你对本文有任何疑问或者高见,欢迎添加公众号lifeofcoder共同交流探讨(添加公众号可以获得楼主最新博文推送以及”Java高级架构“上10G视频和图文资料哦)。
更多推荐
所有评论(0)