1

私は、リクエストに応じてアーティファクトを構築するために何千もの小さなファイルを使用するJavaWebアプリケーションに取り組んでいます。これらのファイルをディスク全体で実行して常に見つけるのではなく、これらのファイルをメモリにマップできれば、システムのパフォーマンスが向上すると思います。

Linuxでmmapについて聞いたことがありますが、その概念の基本的な理解は、ファイルがディスクから読み取られると、ファイルの内容がメモリのどこかにキャッシュされ、その後のアクセスが速くなるということです。私が考えていることはその考えに似ていますが、私のWebアプリが最小限の要求時間応答のために初期化しているので、mmap可能なファイルのセット全体をメモリに読み込みたいという点が異なります。

ここでの私の思考訓練の1つの側面は、ファイルがすべてタール化され、何らかの方法で仮想ファイルシステムとしてJVMにマウントされた場合、ファイルをjvmメモリにすばやく取り込むことができるということです。現状では、現在の実装がソースファイルのセットを調べて、ディスク上にあるものをすべて把握するのに数分かかる場合があります。これは、基本的に300,000を超えるファイルのファイル統計を実行しているためです。

tarファイルから情報を読み取ることができるapacheVFSプロジェクトを見つけましたが、「また、tar全体をメモリに読み込んで保持する」などの指定ができるかどうかは、ドキュメントからはわかりません。

ここでは、マルチスレッド環境について話しています。アーティファクトは、通常、300,000以上のソースファイルの完全なセットから約100の異なるファイルをつなぎ合わせて、1つの応答を作成します。したがって、仮想ファイルシステムソリューションが何であれ、スレッドセーフでパフォーマンスが高い必要があります。ここでは、ファイルの読み取りについてのみ説明しており、書き込みについては説明していません。

また、32ギガのRAMを搭載した64ビットOSを実行しており、300,000ファイルは約1.5〜2.5ギガのスペースを占有します。確かに、2.5ギガバイトのファイルを300Kの小さな数キロバイトサイズのファイルよりもはるかに高速にメモリに読み込むことができます。

入力ありがとうございます!

  • ジェイソン
4

8 に答える 8

1

すぐにアクセスする必要があるファイルが 300,000 個ある場合は、リレーショナル データベースではなく、http://www.space4j.org/のような単純なキーと値のデータベースを使用できます。これは起動時間の短縮にはなりませんが、実行時の速度が大幅に向上する可能性があります。

于 2009-01-18T13:09:55.960 に答える
1

すべてのファイルを JAR に入れて、それをクラスパスに置くことができます。Java は、いくつかの組み込みのトリックを使用して、JAR ファイルからの読み取りを非常に高速にします。これにより、すべてのファイルのディレクトリが RAM に保持されるため、ファイルを見つけるためにディスクにアクセスする必要がなくなります (これは、読み込みを開始する前に発生します)。

JVM は JAR 全体を一度に RAM にロードすることはありません。マシンがスワッピングを開始するため、とにかくそうしたくないでしょう。ただし、ファイルを常に開いたままにしておくため、ファイルリソースを開いたり閉じたりする時間を失うことはないため、断片を非常に迅速に見つけることができます。

また、この単一のファイルを常に使用しているため、OS がそのファイルをファイル キャッシュに長く保持する可能性があります。

最後に、JAR の圧縮を試みることができます。これは悪い考えのように聞こえるかもしれませんが、試してみてください。小さなファイルが非常によく圧縮されている場合、現在の CPU で解凍する時間は、ディスクからデータを読み取る時間よりもはるかに短くなります。中間データをどこにも保持する必要がない場合は、圧縮されていないデータをファイルに書き込む必要なくクライアントにストリーミングできます (これではアイデア全体が台無しになります)。これの欠点は、CPU サイクルを消費することです。CPU がビジー状態の場合 (負荷ツールで確認してください。20% を超えている場合は緩みます)、プロセス全体が遅くなります。

つまり、HTTP プロトコルを使用している場合は、圧縮されたデータを送信していることをクライアントに伝えることができます。この方法では、データを解凍する必要がなく、非常に小さなファイルをロードできます。

JAR ソリューションの主な欠点: サーバーが稼働している限り、JAR を置き換えることはできません。したがって、ファイルを置き換えると、サーバーを再起動する必要があります。

于 2008-12-03T10:29:59.860 に答える
0

明確にするためにmmap()、Unix ライクなシステムでは、ファイル自体にアクセスすることはできません。ファイルの内容をメモリとしてメモリ内で利用できるようにするだけです。open()を使用して、含まれているファイルをさらに開くことはできません。mmap()「可能なファイルのセット」などというものはありません。

最初にすべての「テンプレート」をロードし、それぞれの名前のハッシュなどの単純なものに基づいてそれらをすばやく見つけるパスを追加することはできませんか? これにより、メモリを活用して、任意のテンプレートに対して O(1) アクセスに到達できるはずです。

于 2008-12-03T10:02:31.023 に答える
0

あなたはまだ古いメモリ/ディスクモードについて考えていると思います。

mmapその古いメモリ/ディスクのことはもうなくなっているので、ここでは役に立ちません。ファイルを mmap すると、カーネルは仮想メモリへのポインタを返して、ユーザーが自分の裁量で使用できるようにします。ファイルを実際のメモリに一度にロードすることはありませんファイルの一部であり、要求しているページのみが読み込まれます。(つまり、メモリ ページで、通常は約 4KB です。)

これらの 300k ファイルは、約 1.5GB から 2.5GB のディスク容量を必要とします。サーバーに 2 ギガバイト (またはできれば 4 ギガバイト) の RAM を追加できる可能性がある場合は、ディスク キャッシュにファイルをロードするのに十分RAM があれば、そのディスクの読み取りを OS に任せたほうがよいでしょうそれは、それらの read() がディスクにヒットすることさえありません。(noatime でボリュームをマウントしていない場合は、inode に atime を保存します。)

ファイルを read() してメモリに取り込み、そこから提供しようとする場合、OS には他に関係があるため、スワップではなく常にRAMにあることを確認する方法があります。数時間使用していないメモリのその部分。

OS がディスク キャッシュを行うのに十分な RAM があり、実際にファイルをロードしたい場合は、階層を通過してすべてのファイルを読み取る小さなスクリプト/プログラムをいつでも実行できます。(他に何もしません。)OSにディスクからメモリディスクキャッシュにそれらをロードさせますが、OSがメモリを必要とする場合にそれらがそこにとどまるかどうかを知る方法はありません。したがって、私が前に言ったように、OS にそれを処理させ、十分な RAM を与える必要があります。

varnishアーキテクト ノートを読む必要があります。ここでは、phk が彼自身の言葉で説明しています。なぜあなたが達成しようとしていることは、OS に委ねた方がはるかに優れているのか、OS は、常に、これまでに、RAM の内容と内容をよりよく知っている JVM を知っています。いいえ。

于 2008-12-03T10:04:14.810 に答える
0

Linux を使用している場合は、古き良きRAM ディスクを試してみます。現在のやり方に固執し、IO コストを大幅に削減できます。JVM メモリにバインドされていないため、コンテンツを簡単に置き換えることができます。

あなたがVFSについて話していたように、それにはRAMディスクプロバイダーもありますが、それでもネイティブRAMディスクアプローチを最初に試します.

于 2008-12-03T11:00:31.700 に答える
0

必要なのは、すべての情報をHashTableにロードすることです。

名前をキーとして、内容を値として使用してすべてのファイルをロードすると、考えているセットアップよりも桁違いに速く簡単に作業できるようになります。

于 2008-12-03T14:29:53.183 に答える
0

これらすべてのファイルにすばやくアクセスする必要がある場合は、それらをメモリにロードできますが、ファイルとしてロードすることはしません。これらのデータを、ある種のオブジェクト構造 (最も単純な形式では単なる文字列) に入れます。

私がすることは、使用しているパラメーターからファイルをオブジェクト構造として返すサービスを作成することです。次に、このサービスにキャッシング メカニズムを実装します。あとは、キャッシュを調整するだけです。本当にすべてをメモリにロードする必要がある場合は、より多くのメモリを使用するようにキャッシュを構成します。一部のファイルが他のファイルよりもはるかに多く使用されている場合は、それらだけをキャッシュするだけで十分な場合があります...

あなたが達成しようとしていることについてもっと知っていれば、おそらくより良い回答ができるでしょう.

于 2008-12-03T10:23:37.703 に答える
0

ファイルを 10 の異なるサーバーに配置し、要求を直接処理する代わりに、クライアントが必要なファイルを見つけることができる URL を含む HTTP リダイレクト (または同等のもの) をクライアントに送信します。これにより、負荷を分散できます。サーバーは迅速な要求に応答するだけで、(大規模な) ダウンロードは複数のマシンに分散されます。

于 2008-12-03T10:34:13.313 に答える