2013-11-27 84 views
17

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

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

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

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

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

回答

1

要获得对写入的确认,您不能使用splice()。

有一个在用户空间AIO的东西,但如果你是在内核中做它可能来找出哪些生物的(块I/O)的生成,并等待这些:

块I/O结构:

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

下面是关于如何执行AIO一些例子:

如果从用户空间做到这一点,并使用的msync它仍然是一种如果它实际上还在旋转生锈,那么它就在空气中。

的msync()文档:

您可能需要软化,以使其更加坚固期待,因为它可能是非常昂贵的实际上是肯定的写入磁盘上写入。

根据诸如断电之类的事情,写保证的“最高”典型标准是修改存储的日志记录操作。日志本身只能追加,您可以在回放时查看条目是否完整。那最后的日记条目可能不完整,所以可能仍有可能丢失。