使用内核AIO和O_DIRECT|O_SYNC
,不会复制到内核缓冲区中,并且可以在数据实际刷新到磁盘时获得细粒度通知。但是,它需要将数据保存在io_prep_pwrite()
的用户空间缓冲区中。
使用splice()
,可以将数据从内核空间缓冲区(管道)直接移动到磁盘,而无需复制它。但是,splice()
在数据排队后立即返回,并且不等待实际写入磁盘。
目标是将数据从套接字移动到磁盘而不复制它,同时确认它已被刷新。如何结合以前的两种方法?
通过将splice()
与O_SYNC
相结合,我希望splice()
能够阻止,并且必须使用多个线程来屏蔽延迟。或者,可以使用异步io_prep_fsync()
/ io_prep_fdsync()
,但这会等待刷新所有数据,而不是特定写入。两者都不完美。
需要的是splice()
与内核AIO的组合,允许零拷贝和异步确认写入,这样单个事件驱动的线程可以将数据从套接字移动到磁盘并在需要时获得确认,但这似乎不受支持。是否有一个好的解决方法/替代方法?
答案 0 :(得分:1)
要获得写入的确认,您不能使用splice()。
用户空间中存在aio内容,但如果您在内核中执行此操作,则可能会发现生成哪些生物(块I / O)并等待这些内容:
阻止I / O结构:
如果您想使用AIO,则需要使用 io_getevents():
以下是有关如何执行AIO的一些示例:
如果你是从用户空间进行操作并使用 msync ,如果它实际上还在旋转生锈,那么它仍然在空中。
msync()docs:
你可能不得不软化期望,以使其更加健壮,因为实际上确保写入是在磁盘上写的可能是非常昂贵的。
根据电源移除等内容,写保证的“最高”典型标准是修改存储的日志记录操作。日志本身仅附加,您可以在播放时查看条目是否完整。最后一个日记条目可能不完整,因此可能仍有可能丢失。