0

私は32GBのRAMと4つのSSDのセットを備えたLinuxボックスをRAID0構成で使用しており、最大スループットは約1GB(ランダムな4k読み取り)であり、それらのファイルにランダムかつ同時にアクセスするための最良の方法を決定しようとしています。 javaを使用します。これまでに見た2つの主な方法は、ランダムアクセスファイルとマップされた直接バイトバッファを使用することです。

ただし、ここで注意が必要です。私はオブジェクト用の独自のメモリキャッシュを持っているので、ファイルに保存されているオブジェクトへの呼び出しは、ページングされたメモリではなくディスクを経由する必要があります(これを防ぐためにLinuxボックスのスワップスペースを無効にしました)。マップされたダイレクトメモリバッファはおそらくスワッピングに依存する最速ですが、これは適切ではありません。A)オブジェクトキャッシュにすべての空きメモリを使用していますが、代わりにマップされたバイトバッファを使用すると、オブジェクトキャッシュの目的である大量のシリアル化オーバーヘッドが発生します。 (私のプログラムはすでにCPUに制限されています)B)マップされたバイトバッファを使用すると、OSはデータがディスクに書き込まれるタイミングの詳細を処理します。つまり、これを自分で制御する必要があります。write(byte [])を実行すると、すぐにディスクに送信されます。これは、ACIDトランザクションを使用していないため、電源障害が発生した場合のデータ破損を防ぐためです。

一方、私は大規模な並行性が必要です。同じファイル内の複数の場所に同時に読み取りと書き込みを行う必要があります(データの破損を防ぐためにオフセット/範囲ロックを使用している間)mappedbytebuffersなしでこれを行う方法がわかりませんが、常に読み取りをキューに入れることができます/書き込みますが、これがスループットにどのように悪影響するかはわかりません。

最後に、読み取りまたは書き込み用に新しいbyte []オブジェクトを作成しているときに状況が発生することはありません。これは、1秒あたりほぼ100000の読み取り/書き込み操作を実行するためです。これらのオブジェクトをすべて割り当ててガベージコレクションすると、プログラムが強制終了します。機密性が高く、すでにCPUが制限されているため、byte[]オブジェクトを再利用しても問題ありません。

私がそれらのほとんどを試したので、DBソフトウェアを提案しないでください、そしてそれらは多くの複雑さとCPUオーバーヘッドを追加します。

誰かがこの種のジレンマを持っていましたか?

4

2 に答える 2

3

マップされたダイレクトメモリバッファは、おそらくスワッピングに依存する最速です。

いいえ、十分なRAMがある場合は違います。マッピングは、メモリ内のページをディスク上のページに関連付けます。OSがRAMを回復する必要があると判断しない限り、ページはスワップアウトされません。また、RAMが不足している場合、スワップを無効にすると、パフォーマンスが低下するのではなく、致命的なエラーが発生します。

オブジェクトキャッシュにすべての空きメモリを使用しています

オブジェクトの寿命が非常に長い場合を除いて、ガベージコレクターは実行時に多くの作業を行う必要があるため、これはお勧めできません。キャッシュが小さいほど、全体的なスループットが高くなることがよくあります。

マップされたバイトバッファを使用すると、OSはデータがディスクに書き込まれるタイミングの詳細を処理します。つまり、これを自分で制御する必要があります。write(byte [])すると、すぐにディスクに出力されます

sync実際には、オプションを使用してファイルシステムをマウントしていない限り、そうではありません。そして、故障したドライブ(特にRAID 0)からデータが失われるリスクがあります。

マップされたバイトバッファなしでこれを行う方法がわかりません

ARandomAccessFileがこれを行います。ただし、書き込みごとに少なくともカーネルコンテキストスイッチの料金を支払う必要があります(同期書き込み用にファイルシステムをマウントしている場合、これらの書き込みのそれぞれにディスクのラウンドトリップが含まれます)。

ACIDトランザクションを使用していません

それなら、データはそれほど価値がないと思います。したがって、誰かが電源コードにつまずく可能性について心配するのはやめましょう。

于 2013-02-14T19:00:04.747 に答える
1

マップされたバイトバッファーに対するあなたの異議は持ちこたえません。マップされたファイルはオブジェクト キャッシュとは異なり、アドレス空間を使用しますが、RAM を消費しません。マッピングされたバイト バッファをいつでも同期することもできます (ただし、パフォーマンスはいくらか犠牲になります)。さらに、ランダム アクセス ファイルは同じ装置を裏で使用することになるため、そこにパフォーマンスを保存することはできません。

マップされたバイト バッファが必要なパフォーマンスを得られない場合は、ファイルシステムをバイパスして生のパーティションに直接書き込む必要があります (これは DBMS が行うことです)。そのためには、おそらく、データ処理用の C++ コードを作成し、JNI を介してアクセスする必要があります。

于 2013-02-14T18:06:13.973 に答える