Linux:ファイルを読み取るのにいくつのディスクI / Oが必要ですか?それを最小化するには?[重複]


10

FacebookのHaystackに関するこの論文によると、

NASアプライアンスがディレクトリメタデータを管理する方法が原因で、ディレクトリのブロックマップが大きすぎてアプライアンスで効果的にキャッシュできないため、ディレクトリに数千のファイルを配置することは非常に非効率でした。その結果、10以上のディスク操作が発生して、単一のイメージ。ディレクトリサイズをディレクトリあたり数百のイメージに減らした後でも、結果のシステムでは、通常、イメージをフェッチするために3つのディスク操作が発生します。ファイルの内容を読む。

私はファイルシステムディレクトリのメタデータとiノードが常にOSによってRAMにキャッシュされ、ファイルの読み取りには通常1つのディスクIOしか必要としないと想定していました。

この論文で概説されている「複数のディスクIOが単一のファイルを読み取る」という問題はNASアプライアンスに固有のものですか、それともLinuxにも同じ問題がありますか?

イメージを提供するためにLinuxサーバーを実行する予定です。何らかの方法でディスクIOの数を最小限に抑えることができます。理想的には、OSがすべてのディレクトリとiノードデータをRAMにキャッシュし、各ファイルの読み取りに必要なディスクIOは1つだけであることを確認します。


1
質問への回答ではありませんが、メモリ内のファイルを維持するVarnish(Facebookが使用)はいつでも使用できます。このようにして、1つのイメージがホットになると(同じファイルへの大量の要求)、ディスクIOはまったく使用されません

Darhazer-Linuxのファイルキャッシュ(Varnishが依存する)は既にホットファイルをメモリにキャッシュしているため、Varnishはここでは役に立ちません。静的ファイルサービスのためにNginxの前にVarnishを配置しても、実際には何も追加されません。私の質問は、ファイルがメモリにキャッシュするには大きすぎる/多すぎる場合についてです。それでも、少なくともディレクトリデータとiノードがキャッシュされ、ディスクIOが読み取りごとに1つだけになるようにしたいと思います。

多くのファイルシステムは、inodeをディレクトリ内に格納し、要求の数を1つ減らし、キャッシュヒットの可能性を大幅に高めます。しかし、これはプログラミングの問題ではありません。
Ben Voigt

ファイルシステムを作成するときに、たとえばmke2fs -b 3276832kにすることで、ファイルシステムのブロックサイズを変更できます。ただし、これはそのファイルシステムに小さなファイルがない場合にのみ役立ちます。

回答:


5

Linuxにも同じ「問題」があります。これは私の学生が2年前に発表した論文で、Linuxでの効果が示されています。複数のIOは、いくつかのソースから取得できます。

  • ファイルパスの各ディレクトリレベルでのディレクトリルックアップ。ディレクトリのiノードと1つ以上のディレクトリエントリブロックを読み取る必要がある場合があります。
  • ファイルのiノード

通常のIOパターンでは、キャッシュは非常に効果的であり、シークを減らす方法でiノード、ディレクトリ、およびデータブロックが割り当てられます。ただし、実際にすべてのファイルシステムで共有されている通常の検索方法は、高度にランダム化されたトラフィックには適していません。

ここにいくつかのアイデアがあります:

1)ファイルシステム関連のキャッシュが役立ちます。大きなキャッシュは、ほとんどの読み取りを吸収します。ただし、マシンに複数のディスクを配置する場合、ディスクとRAMの比率によって、キャッシュされる量が制限されます。

2)数百万の小さなファイルを使用しないでください。それらをより大きなファイルに集約し、ファイル名とファイル内のオフセットを保存します。

3)SSDにメタデータを配置またはキャッシュします。

4)そしてもちろん、完全に無秩序なディスク上のディレクトリ形式を持たないファイルシステムを使用します。readdirは線形時間以上かかることはなく、ファイルへの直接アクセスは理想的には対数時間のみです。

キャッシュする必要のあるディレクトリがさらに必要になるため、ディレクトリを小さく(1000未満程度に)維持してもそれほど役に立ちません。


そしてもちろん、完全に古くなったディスク上のディレクトリ形式を持たないファイルシステムを使用してください。readdirは線形時間以上かかることはなく、ファイルへの直接アクセスは理想的には対数時間のみです。
ヨルゲンセン

私はそれを4番目のポイントとして答えに追加しました
dmeister 2012年

@dmeisterいいもの。+1
マゼラン

@dmeisterあなたのリンクは死んでいます。
Don Scott、

1

これは、使用する予定のファイルシステムによって異なります。ファイルデータシステムを読み取る前に:

  • ディレクトリファイルを読み取ります。
  • あなたのファイルのinodeを読む
  • あなたのファイルのセクターを読む

フォルダに膨大な数のファイルが含まれている場合、これはキャッシュに対する大きな不安になります。


I / Oアクセスをリストしている場合は、によって実行さopen()れたものとによって実行されたものを分離する方が興味深い場合がありますread()win.tue.nl/~aeb/linux/vfs/trail.htmlページに、カーネルに関するさまざまな概念のウォークスルーが示されています。(おそらく古くなっているのでしょうか?私には
わかり

0

おそらくRAMよりも多くのディレクトリとiノードデータがあるので、RAMにすべてのディレクトリとiノードデータを保持することはできません。また、そのRAMは他の目的でより適切に使用される可能性があるため、そうしたくない場合もあります。イメージの例では、アクセス頻度の低いイメージのディレクトリエントリよりも、アクセス頻度の高いイメージのデータをRAMにキャッシュした方がよいでしょうか。

とはいえvfs_cache_pressureノブを使用してこれを制御していると思います。「vfs_cache_pressure = 0の場合、カーネルはメモリの圧力のためにデントリとiノードを再利用することはなく、これはメモリ不足の状態を簡単に引き起こす可能性があります。」

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.