コマンドを実行するサーバーが100台あり、各サーバーが出力をNFS共有の同じファイルにリダイレクトする場合、結果ファイルはきちんとインターリーブされますか、それとも破損しますか?
たとえば、100 台のサーバーでこのコマンドを実行する場合:
find / type -f >> /some_server/share/file_list.txt
腐敗しますか?
PS:このコマンドは単なる例であり、実際にファイルを一覧表示しません。
ベストアンサー1
つまり、はい、複数のNFSクライアントの同時書き込みが破損します。
ローカル同時追加は、オペレーティングシステムがファイルがアドオンモードで開くことを知っており、同時にファイルを拡張できる他のプロセスに関係なく、各書き込み呼び出しの前にファイルの現在の終わりを自動的に見つけるため、インターリーブが優れています。
しかし、NFSではそのような幸運はありません。これLinux NFS FAQ具体的に定義:
A9。複数のクライアントでO_APPENDを使用してファイルを開くと、ファイルが破損するのはなぜですか?
回答:NFSプロトコルはアトミック追加の書き込みをサポートしていないため、どのプラットフォームのNFSでも追加の書き込みはアトミックではありません。
ほとんどのNFSクライアント(2.4.20よりも高いカーネルのLinux NFSクライアントを含む)は、「off-to-on」キャッシュの一貫性をサポートします。A8。オープンキャッシュの一貫性に近いものは何ですか?
A:異なるNFSクライアント間で完全なキャッシュ一貫性を達成するためのコストは非常に高いため、NFSはほとんどの日常的なファイル共有タイプの要件を満たすために弱いアプローチを使用します。 [...]アプリケーションがファイルを閉じると、NFSクライアントは保留中の変更をファイルに書き戻し、次のオープン者が変更を確認できるようにします。これはまた、NFSクライアントに、close()の戻りコードを介してアプリケーションにサーバー書き込みエラーを報告する機会を提供します。この動作をほぼ開いたキャッシュ一貫性と呼びます。
国有林庁書き込み操作記録する場所と記録するデータのみが含まれます。クライアントが互いに上書きされないようにするために必要なファイルの終わり位置を中央で調整するための規則はありません。
(3.xに言及することなく、主にLinuxカーネルバージョン2.6について議論しているので、このページは少し古いようですが、カーネルサポートに関してはNFSバージョン4が言及されているので、答えはv4にも当てはまると思います。 .)
最近、LinuxとNFS v3の共有についていくつかのテストを行いました。
for ((i=0 ; i<9999 ; i++)) ; do printf "$id %06d\n" $i >> testfile ; done
同時に、両方のクライアントのシェルループ()に数字を書き込むと、出力が重大に破損します。部分:
barbar 001031
foo 000010
32
foo 000011
33
foo 000012
ここで、あるシステムの最初のループはを使用して行を書き込み、barbar
他のシステムの他のループはfoo
行を書き込みます。行はbarbar 001032
行と同じ位置から書かれておりfoo 000010
、長い行の最後の番号だけが見えるというべきでしょうか。 (この場合、リダイレクトはループの内側にあるため、実際には各ファイルが開いて閉じますが、printf
ファイルが開いたときに最後を見つけるのにのみ役立ちます。)
ファイルが常に開いたままになると、クライアントシステムはファイルが閉じられたときにのみサーバーに変更を書き込むことを約束するため、より大きなブロックを上書きできます。ファイルを開いている間にファイルを切り捨ててもファイルは消去され、ファイルが閉じられたときに他のクライアントがそれを書き込むのを防ぐことができないため、それは大きく変わりません。