7

write()Linux と FreeBSD の両方で実行されるプログラムを作成しています。データが誤って失われないように、物理デバイス上のファイルにデータが実際に書き込まれていることを確認したいと考えています(例: 、電源が失われた、プロセスが予期せず中断されたなど)。

OPEN(2) のマニュアル ページによると、Linux (2.6 以降) ではO_DIRECT同期ですが、パフォーマンスに問題がある可能性があります。FreeBSD では、O_DIRECT同期が保証されておらず、問題が発生する可能性もあります。

では、Linux では同期書き込みを保証するのはどちらO_DIRECTO_SYNCですが、パフォーマンスが優れているのはどちらでしょうか?

O_DIRECTFreeBSD では、同期書き込みを保証するために、(1) + fsync()(2)O_DIRECT | O_SYNCまたは (3)O_SYNC単独で、どのオプションが最高のパフォーマンスを発揮しますか?

4

3 に答える 3

3

O_DIRECT基本的に、Oracle はカーネルのバッファ キャッシュ層をバイパスして独自のキャッシュを実行するためだけに存在します。セマンティクスが明確に定義されておらず、実行できる読み取りのサイズと配置に恣意的な制限があり、通常は使用しないでください。O_SYNC必要な効果が得られるはずですが、電源障害やクラッシュに対して堅牢な基盤となるファイルシステムがなければ、それでもニーズを満たすには十分ではない可能性があります.

于 2013-10-18T01:25:53.187 に答える
1

では、Linux では同期書き込みを保証するのはどちらO_DIRECTO_SYNCですが、パフォーマンスが優れているのはどちらでしょうか?

少なくとも Linux で@roland-smith が述べたように、データが不揮発性メディアに到達したことを保証O_DIRECT しないため、このステートメントは正しくありません。特定の環境 (たとえば、バッテリでバックアップされた SCSI コントローラを備えたディスクを表すブロック デバイスへの直接書き込み) でその保証を提供する場合がありますが、一般的なケース (たとえば、ext4 内のファイルへの書き込み) ではこれに頼ることはできません。単一の SATA ハード ディスクによってのみバッキングされるファイル システム) は、少なくとも次の理由によります。

  • O_DIRECTファイルシステム内のファイルで、停電クラッシュ後にデータを取得するために必要なメタデータが書き込まれることを保証しません
  • 元の呼び出しが完了する前に、カーネルが I/O をハードウェアに送信しましたが、I/O は揮発性のハードウェアキャッシュにのみ存在します。

上記のシナリオでは、突然の電源喪失は、I/O が成功していないのに、プログラムが成功したと考えていたことを意味します。最近では、Linux の open(2) の man ページに次のように書かれています。

フラグ自体はデータを同期的に転送しようとしますが、データと必要なメタデータが転送されるO_DIRECTというフラグの保証はありません。O_SYNC同期 I/O を保証するにO_SYNCは、 に加えて を使用する必要がありますO_DIRECT。詳細については、以下の注を参照してください。

与えられたシナリオでは、Linux で同期書き込みですべての書き込みを保証する唯一の方法は、使用するO_SYNC(速度が低下する) か、fsync()I/O ごとに実行する (システムコールを 2 回実行したため遅くなる可能性があります) ことです。速度が心配な場合は、使用するO_SYNCのをやめて、代わりにできるだけ大きなバッチで書き込み、次にfsync()バッチの後に書き込みます。また、データの整合性が心配な場合は、すべての呼び出し (およびその他)の戻りコードでエラーチェックする必要があることに注意してください。fsync()write()close()

「O_DIRECTの本当の意味は何ですか?」に関するこの回答を参照してください。詳細とリンクについては。

O_DIRECTFreeBSD では、同期書き込みを保証するために、(1) + fsync()(2)O_DIRECT | O_SYNCまたは (3) O_SYNC単独で、どのオプションが最高のパフォーマンスを発揮しますか?

あなたは Linux と同様の状況にあります (上記参照) が、3 つの選択肢のうち、3 つ目 (O_SYNC単独) が最も速いと思います。FreeBSD open(2) の man ページには、次のように書かれていO_DIRECTます。

O_DIRECT は、読み取りと書き込みのキャッシュ効果を最小化または排除するために使用できます。システムは、読み取りまたは書き込みデータのキャッシュを回避しようとします。データのキャッシュが避けられない場合は、データがキャッシュに与える影響を最小限に抑えます。注意して使用しないと、このフラグを使用するとパフォーマンスが大幅に低下する可能性があります。

一般的な注意: を使用O_DIRECTしても、すべての I/O が高速になるとは限りません。これは、ワークロード (I/O サイズ、I/O 頻度、I/O がシーケンシャルかランダムか、同期の頻度など) によって異なります。マージなどへの影響) および I/O の送信方法 (同期対非同期)。

于 2020-07-29T06:40:21.280 に答える