使用内核AIO和O_DIRECT|O_SYNC时,不会将其复制到内核缓冲区中,并且在实际将数据刷新到磁盘时,可以获得细粒度的通知。但是,它要求将数据保留在io_prep_pwrite()的用户空间缓冲区中。

使用splice(),可以将数据从内核空间缓冲区(管道)直接移到磁盘上,而无需复制数据。但是,splice()在数据排队后立即返回,并且不等待实际写入磁盘。

目的是将数据从套接字移动到磁盘,而无需复制数据,同时确认已清除数据。如何结合之前的两种方法?

通过将splice()O_SYNC结合使用,我希望splice()能够被阻止,并且必须使用多个线程来掩盖延迟。或者,可以使用异步io_prep_fsync()/io_prep_fdsync(),但这将等待所有数据被刷新,而不是等待特定的写入。两者都不是完美的。

所需要的是splice()与内核AIO的组合,允许零复制和异步确认写入,以便单个事件驱动的线程可以将数据从套接字移动到磁盘并在需要时获得确认,但这似乎并不被支持。有没有好的解决方法/替代方法?

最佳答案

要确认写入,您不能使用splice()。

用户空间中有aio内容,但是如果您在内核中进行操作,则可能会发现生成了哪些bio(块I/O)并等待它们:

块I/O结构:

  • http://www.makelinux.net/books/lkd2/ch13lev1sec3

  • 如果要使用AIO,则需要使用 io_getevents():
  • http://man7.org/linux/man-pages/man2/io_getevents.2.html

  • 以下是一些有关如何执行AIO的示例:
  • http://www.fsl.cs.sunysb.edu/~vass/linux-aio.txt

  • 如果您是从用户空间执行此操作并使用 msync 的话,那么它实际上还处于起步阶段,即使它实际上正在旋转 rust 。

    msync()文档:
  • http://man7.org/linux/man-pages/man2/msync.2.html

  • 您可能必须降低期望以使其更健壮,因为实际上要确保将写操作最终写在磁盘上可能会非常昂贵。

    鉴于断电之类的东西,写保证的“最高”典型标准是修改存储的日志记录操作。日志本身仅是追加的,播放时可以查看条目是否完整。最后的日记条目可能不完整,因此可能仍然会丢失某些内容。

    关于linux - 写入磁盘时,Linux splice()+内核AIO,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20239939/

    10-10 15:06