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 に答える