O_DIRECT 与 AIO_RAW
Posted
技术标签:
【中文标题】O_DIRECT 与 AIO_RAW【英文标题】:O_DIRECT vs. AIO_RAW 【发布时间】:2013-04-06 13:41:47 【问题描述】:在使用 POSIX 异步 I/O 时,使用 O_DIRECT
和 AIO_RAW
有什么区别吗?或者我应该/我可以同时使用两者吗?我们正在开发 NoSQL 数据库服务器,并正在研究如何在 POSIX 系统上提高异步 I/O 的效率。
open(2):
O_DIRECT 尽量减少进出该文件的 I/O 的缓存影响。一般来说,这会降低性能,但它在 特殊情况,例如当应用程序进行自己的缓存时。 文件 I/O 直接从用户空间缓冲区完成。
aiocb(5):
您可以在 aio_flags 结构成员中设置 AIO_RAW 标志位 当对原始设备分区执行异步 I/O 时。 当 AIO_RAW 标志位被设置时,异步 I/O 可能 更高效。
【问题讨论】:
Linux 上的 aio_write 不是每次都产生一个线程吗?在我看来,这总是一个失败的提议——最好不要使用 AIO(至少在 Linux 上,直到它变得更好)。 @JohnZwinck 这里有一个关于这个主题的有趣讨论***.com/questions/87892/…,上面写着"Direct, unbuffered I/O is only really useful for transactional databases, and those tend to write their own threads or processes to manage their disk I/O."
——这是我们正在开发事务型 NoSQL 数据库服务器产品时的场景。我们管理自己的用户线程池。
我并不是说不要尝试直接的、无缓冲的 I/O。我是说考虑不使用 AIO。这几乎就是您链接的页面所说的:避免使用 AIO。如果需要,请使用 O_DIRECT,但不要使用 AIO_RAW,因为不要使用 AIO。 :)
@JohnZwinck 我认为只要我们管理自己的用户线程池就可以了; POSIX AIO 的好处是它适用于每个文件系统(ext2、ext3、jfs、xfs 和 nfs)和 POSIX 系统,这样我们就不必多次编写相同的代码来制作统一的设备接口。
【参考方案1】:
发问者从未具体说明他们支持哪些操作系统(一个链接指向 Linux 手册页,另一个指向 SCO 手册页),因此很难在没有猜测的情况下回答这个问题。
在撰写本文时,Linux 不支持 AIO_RAW
,因为 glibc 的 struct aiocb
没有 aio_flags
成员(https://www.gnu.org/software/libc/manual/html_node/Asynchronous-I_002fO.html)并且内核 AIO(不是 POSIX)不支持AIO_RAW
值。所以:
使用 O_DIRECT 和 AIO_RAW 有什么不同吗?或者我应该/我可以同时使用两者吗?
是的,因为并非所有支持 POSIX AIO 的操作系统(例如 Linux)都允许您设置 AIO_RAW
,并且在某些情况下您肯定不能同时使用两者。此外,在某些操作系统(如 Linux)上,O_DIRECT
可以用于文件系统和设备上的文件,而AIO_RAW
仅适用于“原始设备”。从 dt 源代码来看,AIO_RAW
似乎仅在 HP-UX 和 SCO Unix 上受支持,因此它可能在其他操作系统中使用有限。
【讨论】:
以上是关于O_DIRECT 与 AIO_RAW的主要内容,如果未能解决你的问题,请参考以下文章
从具有 O_DIRECT 的 HDD 读取()失败并显示 22(EINVAL,无效参数)
writev(或pwritev)会与c中的O_DIRECT冲突吗?
`O_DIRECT | 有啥区别? O_SYNC` + write() 和 `O_DIRECT` + write() + fsync()