【问题标题】:Is it safe to use O_DIRECT without O_SYNC?在没有 O_SYNC 的情况下使用 O_DIRECT 是否安全?
【发布时间】:2014-06-16 18:37:27
【问题描述】:

我有一个 linux 应用程序,可以将数据流式传输到直接连接的 SAS 存储阵列上的文件。它填充大缓冲区,以 O_DIRECT 模式写入它们,然后回收缓冲区(即再次填充它们等)。我不需要使用 O_SYNC 来保证数据完整性,因为我可以忍受崩溃、延迟写入等导致的数据丢失。我主要对高吞吐量感兴趣,而且在没有 O_SYNC 的情况下我似乎可以获得更好的性能。但是,我想知道它是否安全:如果使用 O_DIRECT 而不是 O_SYNC,那么 write() 系统调用究竟何时返回?

  • 如果在对存储阵列缓存的 DMA 完成后 write() 返回,那么我的应用程序可以安全地再次填充缓冲区。阵列本身处于回写模式:它最终会写入磁盘,这对我来说是可以接受的。

  • 如果写入在 DMA 启动后立即返回(但尚未完成),则我的应用程序不安全,因为它会在 DMA 仍在进行时覆盖缓冲区。显然我不想写损坏的数据;但在这种情况下,我也无法确定缓冲区的 DMA 何时完成并且可以安全地重新填充。

(实际上有几个并行线程,每个线程都有自己的缓冲区池,尽管这对于上面的问题可能并不重要。)

【问题讨论】:

    标签: linux io filesystems linux-device-driver


    【解决方案1】:

    当 write 调用返回时,您可以毫无危险地重用缓冲区。您不知道写入已写入磁盘,但您表示这对您来说不是问题。

    一个支持参考是http://www.makelinux.net/ldd3/chp-15-sect-3,其中指出:

    例如,使用直接 I/O 需要 write 系统调用 同步运行;否则应用程序不知道何时 可以重用其 I/O 缓冲区。

    【讨论】:

    • 谢谢。那么您知道使用 O_DIRECT 时 O_SYNC 有什么不同吗?因为它看起来像有或没有 O_SYNC,所以 write() 仅在缓冲区已传输到存储阵列的缓存时才返回。 (阵列处于回写模式,因此一旦所有数据都在其缓存中,它就会发出完成信号。)然而,如果没有 O_SYNC,我确实看到 ext4 和 xfs 的吞吐量提高了约 30%,阵列的配置保持不变.
    • O_DIRECT 仅用于最小化或消除操作系统的缓存,因此我想当您将 O_SYNC 与 O_DIRECT 一起使用时可能会刷新一些缓存数据。此外,O_SYNC 将强制刷新文件的元数据,这会降低性能。
    • O_DIRECT 表示您将绕过 Linux 操作系统页面缓存,但即使写入完成,您也不知道数据是否仍在属于磁盘的易失性缓存中(即您知道“磁盘”有数据,但你不知道它是否在稳定的媒体上,可以在断电后幸存下来)。要知道写入是在非易失性介质上,您需要使用O_SYNC 标志(在Linux 上)或fsync() 函数。请参阅serverfault.com/a/585427/303019 了解为什么存在速度差异。
    猜你喜欢
    • 2016-04-21
    • 1970-01-01
    • 2020-06-16
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多