【问题标题】:Linux splice() + kernel AIO when writing to diskLinux splice() + 内核 AIO 写入磁盘时
【发布时间】:2013-11-27 10:30:59
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: linux io block splice aio


    【解决方案1】:

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

    在用户空间中有 aio 的东西,但如果你在内核中执行它,它可能会找出生成了哪些 bio(块 I/O)并等待那些:

    块 I/O 结构:

    如果你想使用 AIO,你需要使用 io_getevents():

    以下是一些关于如何执行 AIO 的示例:

    如果您从用户空间执行此操作并使用 msync,如果它实际上还处于生锈状态,那么它仍然有点悬而未决。

    msync() 文档:

    您可能必须降低期望以使其更健壮,因为要确保实际写入实际写入磁盘可能会非常昂贵。

    考虑到诸如断电之类的情况,写入保证的“最高”典型标准是修改存储的日志记录操作。日志本身只是附加的,您可以在回放时查看条目是否完整。最后的日记条目可能不完整,因此仍有可能丢失某些内容。

    【讨论】:

      猜你喜欢
      • 2012-01-20
      • 2011-10-18
      • 2014-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-24
      • 1970-01-01
      相关资源
      最近更新 更多