O_DIRECT 与 AIO_RAW

Posted

技术标签:

【中文标题】O_DIRECT 与 AIO_RAW【英文标题】:O_DIRECT vs. AIO_RAW 【发布时间】:2013-04-06 13:41:47 【问题描述】:

在使用 POSIX 异步 I/O 时,使用 O_DIRECTAIO_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()

O_DIRECT 的真正含义是啥?

Arch LINux 上未定义 O_DIRECT

关于O_DIRECT的那些事儿