17

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

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

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

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

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

4

1 回答 1

1

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

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

块 I/O 结构:

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

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

如果您从用户空间执行此操作并使用msync,如果它实际上还处于旋转状态,它仍然是悬而未决的。

msync() 文档:

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

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

于 2015-05-03T21:04:32.470 回答