私は、すべてのファイルがmd5の合計と等しいファイル名で保存されているファイルストアを含むアプリケーションを管理しています。すべてのファイルは1つのディレクトリに保存されます。現在は数千ありますが、すぐに数百万のファイルがサーバー上にあるはずです。現在のサーバーはext4ファイルシステムでUbuntu 11.10を実行しています。
誰かがディレクトリに多くのファイルを置くのは賢明ではないと私に言った、これはルックアップ時間と信頼性を大幅に増加させるからだ(彼は単一のディレクトリがポイントできる最大ファイルについての話を持っていたので、大きなリンクリストになっていた)。代わりに、彼はサブディレクトリを作成することを提案しました。ファイル名の部分文字列。しかし、これは私のアプリケーションのいくつかのことをはるかに扱いにくくします。
これはまだ本当ですか、または最近のファイルシステム(例:ext4)はこれに対処し、自然にスケーリングするより効率的な方法を持っていますか? Wikipedia にはファイルシステムに関する詳細がありますが、ディレクトリごとの最大ファイル数やルックアップ時間については何も言われていません。
ext3
以降のファイルシステムは ハッシュBツリー ディレクトリインデックスをサポートしています。名前による追加、削除、およびアクセスのみが実行される操作である限り、これは非常によく拡張されます。ただし、ディレクトリを分解することをお勧めします。それ以外の場合は、ディレクトリに他の操作を実行するツール(updatedb
、ls
、du
など)の危険なブービートラップを作成します。エントリが多すぎます。
問題の核心は、必要な1つのファイルのディレクトリiノードを掘り下げることです。一部のファイルシステムは、他のファイルシステムよりもこれをうまく行います。数十億に近い規模のものもありますが、20Kファイルしかない場合は取得するこれらのファイルは著しく高速です。また、ファイル数が多いと、特定のツールで問題が発生し、結果としてバックアップ/復元の問題がはるかに困難になる可能性があります。
たまたま、私自身の開発でまったく同じ問題に遭遇しました(ファイル名としてのmd5sum、そのスケーリング)。私が開発者に勧めたのは、文字列を細かく切ることです。彼らは4人のグループで行ったが、当時私たちがいたファイルシステムでは、多くの人がパフォーマンスの観点から問題があることが判明するため、最初の6つのトリプレットは3つのグループで分割され、残りは端末ディレクトリのファイル名。
4名のグループ:4976/d70b/180c/6142/c617/d0c8/9d0b/bd2b.txt
3人のグループ:497/6d7/0b1/80c/614/2c6/17d0c89d0bbd2b.txt
これにはディレクトリサイズを小さく保つという利点があり、MD5sumはかなりランダムであるため、バランスのとれたディレクトリツリーが作成されます。その最後のディレクトリは、数個以上のファイルを取得することはほとんどありません。そして、コードを操作するのはそれほど難しくありませんでした。私たちは数百万のファイルプロジェクトを扱っているため、スケーリングは非常に重要でした。
現代のファイルシステムは、数百万のファイルであっても、非常に大きなディレクトリを非常にうまく処理します。しかし、従来のツールにはありません。たとえば、「ls」を使用してこのような大きなディレクトリを一覧表示すると、通常はディレクトリ全体が読み取られてソートされるため、かなり長い時間がかかります(ソートを回避するためにls -fを使用できます)。すべてが読み取られるまで、ファイルの表示は開始されません。名前を分割すると、場合によっては役立ちますが、すべてではありません(たとえば、rsyncレプリケーションで名前のツリー全体を収集する必要がある場合もあります)。