質問

私が取り組んでいる製品は、1 日に数千件の測定値を収集し、それらを 64k バイナリ ファイルとして NTFS パーティション (Windows XP) に保存します。運用開始から 1 年が経過すると、1 つのディレクトリに 300,000 を超えるファイルが存在し、その数は増え続けています。このため、Windows エクスプローラーから親/祖先ディレクトリにアクセスするのに非常に時間がかかります。

インデックスサービスをオフにしてみましたが、変化はありませんでした。ファイルの内容をデータベース/zip ファイル/tarball に移動することも検討しましたが、ファイルに個別にアクセスする方が有益です。基本的に、ファイルは依然として研究目的で必要であり、研究者はそれ以外のことに対処するつもりはありません。

これらすべての小さなファイルを処理できるように NTFS または Windows を最適化する方法はありますか?

役に立ちましたか?

解決

ディレクトリ内にファイルが 10,000 個あると、NTFS のパフォーマンスが大幅に低下します。ディレクトリ階層に追加のレベルを作成し、各サブディレクトリに 10,000 個のファイルを含めます。

当然のことながら、これは SVN の人々が採用したアプローチです バージョン1.5. 。デフォルトのしきい値として 1,000 ファイルを使用しました。

他のヒント

実際、NTFS は、16 ビット Windows プラットフォームと互換性のある代替ファイル名の作成を停止するように指示されている限り、ディレクトリ内に 10,000 を超えるファイルが存在する場合でも問題なく動作します。デフォルトでは、NTFS は作成されるファイルごとに「8 ドット 3」のファイル名を自動的に作成します。Windows はディレクトリ内のファイルを調べて、作成中の名前がまだ使用されていないことを確認するため、ディレクトリ内に多数のファイルがある場合、これが問題になります。NtfsDisable8dot3NameCreation レジストリ値を 1 に設定すると、「8 dot 3」ネーミングを無効にできます。この値は、HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem レジストリ パスにあります。「8 dot 3」という名前のファイルは、非常に古いバージョンの Windows 用に作成されたプログラムでのみ必要とされるため、この変更を行っても安全です。

この設定を有効にするには再起動が必要です。

パフォーマンスの問題は、単一ディレクトリ内の膨大な量のファイルが原因で発生します。それを解消すれば、大丈夫なはずです。これは NTFS 固有の問題ではありません。実際、大規模な UNIX システム上のユーザーのホーム ファイルやメール ファイルでよく発生します。

この問題を解決する明らかな方法の 1 つは、ファイル名に基づいた名前のフォルダーにファイルを移動することです。すべてのファイルのファイル名が同様の長さであると仮定します。ABCDEFGHI.db、ABCEFGHIJ.db など、次のようなディレクトリ構造を作成します。

ABC\
    DEF\
        ABCDEFGHI.db
    EFG\
        ABCEFGHIJ.db

この構造を使用すると、名前に基づいてファイルをすばやく見つけることができます。ファイル名が可変長の場合は、ファイルが属するディレクトリを決定するために、最大長を選択し、先頭にゼロ (またはその他の文字) を追加します。

私は過去に、たとえばファイル名の最初の文字と 2 番目の文字によってファイルをディレクトリのネストされた階層に分割することで大幅な改善が見られたことがあります。そうすれば、各ディレクトリに過剰な数のファイルが含まれることはなくなります。ただし、データベース全体の操作は依然として遅いです。

Solid File System のようなものを使用してみてください。

これにより、アプリケーションが物理ディスクであるかのようにマウントできる仮想ファイル システムが得られます。アプリケーションは多数の小さなファイルを認識しますが、ハード ドライブ上に存在するファイルは 1 つだけです。

http://www.eldos.com/solfsdrv/

ファイル名を計算できれば、ファイルを日付ごとにフォルダーに分類して、各フォルダーに特定の日付のファイルのみを含めることができる可能性があります。月と年の階層を作成することもできます。

また、たとえば 1 年以上古いファイルを別の (ただしアクセス可能な) 場所に移動できますか?

最後に、繰り返しになりますが、これには名前を計算できる必要があります。ファイルに直接アクセスした方が、エクスプローラーでファイルを開こうとするよりもはるかに速いことがわかります。たとえば、次のように言う
notepad.exe "P:\ath o\your\filen.ame"
ディレクトリのリストを取得しなくても、必要なファイルのパスがわかっていると仮定すると、コマンド ラインからの実行は実際には非常に速いはずです。

一般的なトリックの 1 つは、単純にいくつかのサブディレクトリを作成し、ファイルを分割することです。

たとえば、大量の HTML ページを生成できる自動コード ドキュメント プログラムである Doxygen には、2 レベルの深いディレクトリ階層を作成するオプションがあります。その後、ファイルは最下位のディレクトリに均等に分散されます。

単一のディレクトリに何十万ものファイルがあると、確かに NTFS が機能しなくなるため、それに対してできることはあまりありません。1 つの大きな tarball やデータベースなど、より実用的な形式でデータを保存することを再検討する必要があります。

読み取りごとに個別のファイルが本当に必要な場合は、すべてを同じディレクトリに置くのではなく、複数のサブディレクトリに分類する必要があります。これを行うには、ディレクトリの階層を作成し、ファイル名に応じて異なるディレクトリにファイルを置きます。この方法では、ファイル名だけを知っていれば、ファイルの保存とロードを行うことができます。

私たちが使用する方法は、ファイル名の最後の数文字を逆順に取り、そこから 1 文字のディレクトリを作成することです。たとえば、次のファイルについて考えてみましょう。

1.xml
24.xml
12331.xml
2304252.xml

次のようにディレクトリに並べ替えることができます。

data/1.xml
data/24.xml
data/1/3/3/12331.xml
data/2/5/2/4/0/2304252.xml

このスキームにより、各ディレクトリに 100 を超えるファイルが存在することがなくなります。

私は過去に何度もこの問題に遭遇しました。日付ごとに保存したり、小さなファイルがたくさん残らないように日付の下にファイルを圧縮したりしてみました。これらはすべて、データを NTFS 上に多数の小さなファイルとして保存するという実際の問題に対する応急処置でした。

ZFS または小さなファイルをより適切に処理するその他のファイル システムを使用することもできますが、それでも立ち止まって、小さなファイルを保存する必要があるかどうかを確認してください。

私たちの場合、最終的には、特定の日付のすべての小さなファイルが、それらを解析するための単純な区切り文字を使用して TAR タイプの方法で追加されるシステムに行きました。ディスク ファイルは 120 万から数千未満になりました。NTFS は小さなファイルをうまく処理できないため、実際にはロードが速くなり、いずれにしてもドライブは 1MB ファイルをよりよくキャッシュできました。私たちの場合、ファイルの正しい部分を見つけるためのアクセスと解析時間は、実際のストレージと保存されたファイルのメンテナンスに比べて最小限でした。

ファイルをサブディレクトリに置くことは別として。

個人的には、そのフォルダーへのインターフェイスを同じに保つ、つまりすべてのファイルが個別のファイルとして表示されるアプリケーションを開発します。次に、アプリケーションのバックグラウンドで実際にこれらのファイルを取得し、それらをより大きなファイルに結合します (サイズは常に 64k であるため、必要なデータを取得するのは比較的簡単です)。混乱を解消します。

したがって、ユーザーが必要なファイルに簡単にアクセスできるようにするだけでなく、すべての構造をより詳細に制御できるようになります。

大量の小さなファイルに適したファイルシステム (ZFS を備えた Solaris など) を使用する別のサーバーにそれらをプッシュすることを検討してください。

データに意味のあるカテゴリ的な側面がある場合は、それらをディレクトリ ツリーにネストできます。速度の低下は、ファイル自体の数の多さではなく、1 つのディレクトリ内のファイルの数が原因だと思います。

最も明白で一般的なグループ化は日付によるもので、各リーフ ディレクトリ内のファイル数が比較的安全な制限 (1 ~ 3k) で 3 層の入れ子構造 (年、月、日) になります。

たとえファイルシステムやファイルブラウザのパフォーマンスを改善できたとしても、これはあと 2 年か 3 年後には直面する問題のようです...0.3 ~ 100 万のファイルのリストを確認するだけでもコストがかかるため、ファイルのより小さいサブセットのみを確認する方法を見つけた方が長期的には良いかもしれません。

「find」(cygwin または mingw で) などのツールを使用すると、ファイルを参照するときにサブディレクトリ ツリーの存在が問題にならなくなります。

毎日、タイムスタンプを使用してフォルダーの名前を変更します。

アプリケーションがファイルを c: eadings に保存している場合は、午前 0 時に Reading の名前を変更し、新しい空のフォルダーを作成するようにスケジュールされたタスクを設定します。

その後、毎日 1 つのフォルダーが取得され、それぞれのフォルダーには数千のファイルが含まれます。

この方法をさらに拡張して、月ごとにグループ化することができます。たとえば、C: eading は c:\Archive\ September\22 になります。

製品の保存中にフォルダーの名前を変更しないように、タイミングに注意する必要があります。

未知の数のファイルに対応できるフォルダー構造を作成するには、次のシステムが好きです。

ファイル名を固定長の部分に分割し、最後を除く部分ごとにネストされたフォルダーを作成します。

このシステムの利点は、フォルダー構造の深さがファイル名の長さまでしか増加しないことです。したがって、ファイルが数値シーケンスで自動的に生成される場合、その構造は必要なだけ深くなります。

12.jpg -> 12.jpg
123.jpg -> 12\123.jpg
123456.jpg -> 12\34\123456.jpg

このアプローチでは、フォルダーにファイルとサブフォルダーが含まれることになりますが、これは合理的なトレードオフだと思います。

そして、これが 美しい PowerShell のワンライナーですぐに始められます。

$s = '123456'

-join  (( $s -replace '(..)(?!$)', '$1\' -replace '[^\\]*$','' ), $s )
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top