606

1つのディレクトリにいくつのファイルを保持するかは重要ですか?もしそうなら、ディレクトリ内のファイルの数が多すぎます。ファイルが多すぎるとどのような影響がありますか?(これはLinuxサーバー上にあります。)

背景:フォトアルバムのWebサイトがあり、アップロードされたすべての画像の名前が8桁の16進数ID(たとえば、a58f375c.jpg)に変更されています。これは、ファイル名の競合を回避するためです(たとえば、「IMG0001.JPG」ファイルが多数アップロードされている場合)。元のファイル名と有用なメタデータはデータベースに保存されます。現在、imagesディレクトリには約1500個のファイルがあります。これにより、(FTPまたはSSHクライアントを介して)ディレクトリ内のファイルを一覧表示するのに数秒かかります。しかし、それ以外の効果があるとは思えません。特に、画像ファイルがユーザーに提供される速度には影響がないようです。

0〜9とafの16個のサブディレクトリを作成して、画像の数を減らすことを考えました。次に、ファイル名の最初の16進数に基づいて、画像をサブディレクトリに移動します。しかし、FTP / SSHを介してディレクトリが時折リストされることを除いて、そうする理由があるかどうかはわかりません。

4

22 に答える 22

802

FAT32

  • ファイルの最大数:268,173,300
  • ディレクトリあたりのファイルの最大数:2 16-1  (65,535)
  • 最大ファイルサイズ:2 GiB-1 ( LFSなし)、4 GiB-1(あり)

NTFS

  • ファイルの最大数:2 32-1  (4,294,967,295)
  • 最大ファイルサイズ
    • 実装:2  44-2 6バイト(16 TiB-64 KiB)
    • 理論値:2 64-2 6バイト(16 EiB-64 KiB  )
  • 最大ボリュームサイズ
    • 実装:2 32-1 クラスター(256 TiB-64 KiB)
    • 理論値:2  64-1クラスター(1 YiB-64 KiB

ext2

  • ファイルの最大数:10 18
  • ディレクトリあたりのファイルの最大数:〜1.3×10 20(10,000を超えるパフォーマンスの問題)
  • 最大ファイルサイズ
    • 16 GiB(1 KiBのブロックサイズ)
    • 256 GiB(2 KiBのブロックサイズ)
    • 2 TiB(4 KiBのブロックサイズ)
    • 2 TiB(8 KiBのブロックサイズ)
  • 最大ボリュームサイズ
    • 4 TiB(1 KiBのブロックサイズ)
    • 8 TiB(2 KiBのブロックサイズ)
    • 16 TiB(4 KiBのブロックサイズ)
    • 32 TiB(8 KiBのブロックサイズ)

ext3

  • ファイルの最大数:min(volumeSize / 2 13、numberOfBlocks)
  • 最大ファイルサイズ:ext2と同じ
  • 最大ボリュームサイズ:ext2と同じ

ext4

  • ファイルの最大数:2 32-1  (4,294,967,295)
  • ディレクトリあたりのファイルの最大数:無制限
  • 最大ファイルサイズ:2 44-1 バイト(16 TiB-1)
  • 最大ボリュームサイズ:2 48-1 バイト(256 TiB-1)
于 2009-01-21T19:16:51.000 に答える
205

単一の ext3 ディレクトリに 800 万を超えるファイルがありました。readdir()で使用されるlibc findlsおよびこのスレッドで説明されている他のほとんどのメソッドは、大きなディレクトリを一覧表示します。

lsこの場合、 とfindが遅い理由readdir()は、一度に 32K のディレクトリ エントリしか読み取れないためです。そのため、低速のディスクでは、ディレクトリを一覧表示するために多数の読み取りが必要になります。この速度の問題には解決策があります。私はそれについてかなり詳細な記事を書きました: http://www.olark.com/spw/2011/08/you-can-list-a-directory-with-8-million-files-but-not-with- ls/

重要な点は次のとおりです。libcに基づくものではなく、getdents()直接使用する- http://www.kernel.org/doc/man-pages/online/pages/man2/getdents.2.htmlreaddir()バッファーを指定できるようにするディスクからディレクトリ エントリを読み取るときのサイズ。

于 2011-08-11T20:19:45.087 に答える
74

88,914 個のファイルを含むディレクトリがあります。あなたのように、これはサムネイルの保存と Linux サーバーで使用されます。

FTP または php 関数を介してリストされたファイルは確かに遅いですが、ファイルを表示する際にもパフォーマンスが低下します。たとえば、www.website.com/thumbdir/gh3hg4h2b4h234b3h2.jpg の待機時間は 200 ~ 400 ミリ秒です。ディレクトリに約100個のファイルがある別のサイトでの比較として、画像はわずか40msの待機後に表示されます。

ほとんどの人がディレクトリ検索機能がどのように実行されるかを書いたばかりなので、この回答を与えました。これは、親指フォルダーでは使用しません-ファイルを静的に表示するだけですが、ファイルが実際にどのように使用されるかのパフォーマンスに興味があります.

于 2012-07-07T08:33:59.503 に答える
57

Linuxサーバーで使用されている特定のファイルシステムに少し依存します。現在、デフォルトはdir_indexを使用したext3であり、これにより大きなディレクトリの検索が非常に高速になります。

したがって、すでに述べたものを除いて、速度が問題になることはありません。それは、リストに時間がかかるということです。

1つのディレクトリ内のファイルの総数には制限があります。私はそれが間違いなく32000ファイルまで機能したことを覚えているようです。

于 2009-01-21T19:07:58.007 に答える
49

Linuxでは、ファイルが多すぎるディレクトリがある場合、シェルがワイルドカードを展開できない可能性があることに注意してください。Linuxでホストされているフォトアルバムでこの問題が発生します。サイズ変更されたすべての画像を1つのディレクトリに保存します。ファイルシステムは多くのファイルを処理できますが、シェルは処理できません。例:

-shell-3.00$ ls A*
-shell: /bin/ls: Argument list too long

また

-shell-3.00$ chmod 644 *jpg
-shell: /bin/chmod: Argument list too long
于 2009-01-21T19:57:55.737 に答える
27

私は現在、同様の問題に取り組んでいます。階層的なディレクトリ構造があり、イメージ ID をファイル名として使用します。たとえばid=1234567

..../45/67/1234567_<...>.jpg

最後の 4 桁を使用して、ファイルの移動先を決定します。

数千の画像では、1 レベルの階層を使用できます。私たちのシステム管理者は、効率/バックアップ/彼が念頭に置いていた他の理由のために、特定のディレクトリ(ext3)に数千ファイルを超えることを提案しませんでした。

于 2009-01-21T20:52:13.880 に答える
27

参考までに、ファイル システム上に 1,000,000 個のファイルを含むディレクトリを作成ext4し、Web サーバーを介してこれらのファイルにランダムにアクセスしました。そこに 10 個のファイルしかない (たとえば) 以上のものにアクセスすることのプレミアムに気づきませんでした。

これは、数年前にこれを行った私の経験とは根本的に異なります。ntfs

于 2013-11-10T18:39:16.323 に答える
13

私が遭遇した最大の問題は、32ビットシステムです。特定の数を渡すと、「ls」などのツールは機能しなくなります。

その障壁を通過した後、そのディレクトリで何かをしようとすると、大きな問題になります。

于 2009-01-21T19:01:04.323 に答える
10

それは実際に使用されるファイルシステムといくつかのフラグに依存します。

たとえば、ext3には何千ものファイルを含めることができます。しかし、数千年後、それは非常に遅くなりました。主にディレクトリを一覧表示するときだけでなく、単一のファイルを開くときも。数年前、「htree」オプションを取得しました。これにより、ファイル名を指定してiノードを取得するために必要な時間が大幅に短縮されました。

個人的には、サブディレクトリを使用して、ほとんどのレベルを1,000程度以下に抑えています。あなたの場合、IDの最後の2桁を含む256個のディレクトリを作成します。最初の桁ではなく最後の桁を使用して、負荷分散を実現します。

于 2009-01-21T19:08:12.843 に答える
8

ディレクトリパーティションスキームの実装にかかる時間が最小限であれば、私はそれを支持します。初めてコンソールを介して10000ファイルのディレクトリを操作することを含む問題をデバッグする必要があるとき、あなたは理解するでしょう。

例として、F-Spotは写真ファイルをYYYY \ MM \ DD \ filename.extとして保存します。これは、約20000枚の写真コレクションを手動で操作するときに処理しなければならなかった最大のディレクトリが約800ファイルであることを意味します。これにより、サードパーティのアプリケーションからファイルをより簡単に閲覧できるようになります。ソフトウェアがソフトウェアのファイルにアクセスする唯一のものであると思い込まないでください。

于 2009-01-21T19:55:10.143 に答える
7

それは絶対にファイルシステムに依存します。最近のファイルシステムの多くは、適切なデータ構造を使用してディレクトリの内容を格納しますが、古いファイルシステムはエントリをリストに追加するだけであることが多いため、ファイルの取得はO(n)操作でした。

ファイルシステムが正しく機能していても、ディレクトリの内容を一覧表示するプログラムが混乱してO(n ^ 2)ソートを実行する可能性は絶対にあるので、念のため、1つあたりのファイル数を常に制限します。 500以下のディレクトリ。

于 2009-01-21T20:08:12.127 に答える
6

実際、ext3 にはディレクトリ サイズの制限があり、ファイル システムのブロック サイズに依存します。ディレクトリごとのファイルの「最大数」ではなく、ディレクトリごとの「ファイルエントリの保存に使用されるブロックの最大数」があります。具体的には、ディレクトリ自体のサイズは高さ 3 の B ツリーを超えることはできず、ツリーのファンアウトはブロック サイズに依存します。詳細については、このリンクを参照してください。

https://www.mail-archive.com/cwelug@googlegroups.com/msg01944.html

最近、2K ブロックでフォーマットされたファイルシステムでこれに悩まされましたwarning: ext3_dx_add_entry: Directory index full!。別の ext3 ファイルシステムからコピーしているときに、不可解にもディレクトリがいっぱいのカーネル メッセージが表示されました。私の場合、わずか 480,000 個のファイルを含むディレクトリをコピー先にコピーできませんでした。

于 2014-01-21T22:24:43.893 に答える
5

問題は、ファイルをどうするかということです。

Windowsでは、2kを超えるファイルがあるディレクトリは、エクスプローラーでゆっくり開く傾向があります。それらがすべて画像ファイルである場合、サムネイルビューで1,000を超えると非常にゆっくり開く傾向があります。

かつて、システムによって課された制限は32,767でした。今はもっと高くなっていますが、それでもほとんどの状況で一度に処理するにはファイルが多すぎます。

于 2009-01-21T19:07:56.540 に答える
5

「ファイルシステムに依存する」
一部のユーザーは、パフォーマンスへの影響は使用するファイルシステムに依存すると述べています。もちろん。EXT3 のようなファイルシステムは非常に遅くなる可能性があります。lsただし、EXT4またはXFS を使用している場合でも、findFTP などの外部接続を介してフォルダーを一覧表示すると、ますます遅くなるのを防ぐことはできません。

解決策@armandino
と同じ方法を好みます。そのために、PHP で次の小さな関数を使用して、ディレクトリごとに 1000 ファイルになるように ID をファイルパスに変換します。

function dynamic_path($int) {
    // 1000 = 1000 files per dir
    // 10000 = 10000 files per dir
    // 2 = 100 dirs per dir
    // 3 = 1000 dirs per dir
    return implode('/', str_split(intval($int / 1000), 2)) . '/';
}

または、英数字を使用する場合は、2 番目のバージョンを使用できます。

function dynamic_path2($str) {
    // 26 alpha + 10 num + 3 special chars (._-) = 39 combinations
    // -1 = 39^2 = 1521 files per dir
    // -2 = 39^3 = 59319 files per dir (if every combination exists)
    $left = substr($str, 0, -1);
    return implode('/', str_split($left ? $left : $str[0], 2)) . '/';
}

結果:

<?php
$files = explode(',', '1.jpg,12.jpg,123.jpg,999.jpg,1000.jpg,1234.jpg,1999.jpg,2000.jpg,12345.jpg,123456.jpg,1234567.jpg,12345678.jpg,123456789.jpg');
foreach ($files as $file) {
    echo dynamic_path(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>

1/1.jpg
1/12.jpg
1/123.jpg
1/999.jpg
1/1000.jpg
2/1234.jpg
2/1999.jpg
2/2000.jpg
13/12345.jpg
12/4/123456.jpg
12/35/1234567.jpg
12/34/6/12345678.jpg
12/34/57/123456789.jpg

<?php
$files = array_merge($files, explode(',', 'a.jpg,b.jpg,ab.jpg,abc.jpg,ddd.jpg,af_ff.jpg,abcd.jpg,akkk.jpg,bf.ff.jpg,abc-de.jpg,abcdef.jpg,abcdefg.jpg,abcdefgh.jpg,abcdefghi.jpg'));
foreach ($files as $file) {
    echo dynamic_path2(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>

1/1.jpg
1/12.jpg
12/123.jpg
99/999.jpg
10/0/1000.jpg
12/3/1234.jpg
19/9/1999.jpg
20/0/2000.jpg
12/34/12345.jpg
12/34/5/123456.jpg
12/34/56/1234567.jpg
12/34/56/7/12345678.jpg
12/34/56/78/123456789.jpg
a/a.jpg
b/b.jpg
a/ab.jpg
ab/abc.jpg
dd/ddd.jpg
af/_f/af_ff.jpg
ab/c/abcd.jpg
ak/k/akkk.jpg
bf/.f/bf.ff.jpg
ab/c-/d/abc-de.jpg
ab/cd/e/abcdef.jpg
ab/cd/ef/abcdefg.jpg
ab/cd/ef/g/abcdefgh.jpg
ab/cd/ef/gh/abcdefghi.jpg

-versionでわかるように、$intすべてのフォルダーには最大 1000 個のファイルと、1000 個のファイルと 99 個のディレクトリを含む最大 99 個のディレクトリが含まれています...

しかし、多くのディレクトリが同じパフォーマンスの問題を引き起こすことを忘れないでください!

最後に、ファイルの総量を減らす方法を検討する必要があります。ターゲットに応じて、CSS スプライトを使用して、アバター、アイコン、スマイリーなどの複数の小さな画像を組み合わせることができます。または、メディア以外の小さなファイルを多数使用する場合は、それらを JSON 形式などで結合することを検討してください。私の場合、何千ものミニキャッシュがあり、最終的にそれらを 10 個のパックにまとめることにしました。

于 2015-04-17T19:32:38.773 に答える
4

同様の問題に遭遇しました。10,000 を超えるファイルが含まれるディレクトリにアクセスしようとしていました。ファイル リストを作成し、任意のファイルに対して任意のタイプのコマンドを実行するのに時間がかかりすぎていました。

私は自分でこれを行うための小さな php スクリプトを考え出し、ブラウザでタイムアウトしないようにする方法を見つけようとしました。

以下は、問題を解決するために私が書いた php スクリプトです。

FTP のファイルが多すぎるディレクトリ内のファイルの一覧表示

それが誰かを助ける方法

于 2010-11-26T15:37:53.553 に答える
4

出力で大量のファイルを作成するプログラムを実行したことを思い出します。ファイルはディレクトリごとに 30000 でソートされました。生成された出力を再利用しなければならなかったときに、読み取りの問題が発生したことを思い出しません。それは 32 ビットの Ubuntu Linux ラップトップ上にあり、Nautilusでさえディレクトリの内容を表示しましたが、数秒後には表示されました。

ext3 ファイルシステム: 64 ビット システムの同様のコードは、ディレクトリごとに 64000 ファイルを適切に処理しました。

于 2009-01-21T19:13:05.670 に答える
3

これは、いくつが多すぎるかというあなたの質問に完全に答えているわけではありませんが、長期的な問題を解決するためのアイデアは、元のファイルのメタデータを保存することに加えて、それが保存されているディスク上のフォルダーも保存することです-正規化そのメタデータを取り出します。フォルダーが、パフォーマンス、美的、または何らかの理由で快適な制限を超えて大きくなると、2 つ目のフォルダーを作成し、そこにファイルをドロップし始めます...

于 2009-01-21T20:49:25.790 に答える
1

OS の制限を超えない限り、「多すぎる」という単一の数字はありません。ただし、OS に関係なく、ディレクトリ内のファイルが多いほど、個々のファイルにアクセスするのに時間がかかります。また、ほとんどの OS ではパフォーマンスが非線形であるため、10,000 個のファイルから 1 個のファイルを見つけるには 10 倍以上の時間がかかります。次に、1,000 でファイルを検索します。

ディレクトリに多数のファイルがあることに関連する二次的な問題には、ワイルド カード展開の失敗が含まれます。リスクを軽減するために、ディレクトリをアップロード日、またはその他の有用なメタデータで並べ替えることを検討してください。

于 2014-02-16T00:18:19.463 に答える