Azul Zing JVMを使用してLuceneインデックスをRAMに配置します

Google検索のインデックス全体が少なくとも5年間RAMにあります。 Luceneの検索インデックスで同じことを試してみませんか?



最近、RAMは非常に安価になったため、負荷の高いリソースの場合、検索インデックス全体をRAMに配置することで深刻なパフォーマンスの向上を期待できます。



明白な質問は、Luceneが提供するRAMDirectory



クラスにインデックス全体をロードする必要があるかどうかです。



残念ながら、このクラスはガベージコレクター(GC)に非常に深刻な負荷をかけることで知られています。各ファイルは、 byte[1024]



タイプbyte[1024]



フラグメントのリストとして表されます。 また、不必要な同期メカニズムも含まれています。アプリケーションがインデックスを更新する場合(つまり、インデックスを検索するだけではない場合)、 RAMDirectory



加えた変更をディスクに保存する方法の問題は別の問題です。 インデックスを最初にメモリにロードする必要があるため、開始時間も大幅に遅くなります。 この問題のリストに直面して、Lucene開発者はRAMDirectory



を小さなインデックスまたはテスト目的にのみ使用することを推奨することが多く、他の場合はオペレーティングシステムのメモリ管理メカニズムに依存し、 MMapDirectory



クラスを使用してアクセスします。



RAMDirectory



クラスに関するこれらの問題にもかかわらず、開発者はそれを改善するために取り組んでおり、多くのユーザーが既にプロジェクトで使用しています。



最近、 Azulが開発したZing仮想マシンJavaについて学びました。これは、大量のヒープに対しても、一時停止のないガベージコレクターを提供します。 つまり 理論的には、 RAMDirectory



クラスによって生成される重いメモリ負荷は、Zingにとって問題にはなりません。 それをチェックしてみましょう! しかし、最初に、病院内の平均気温を測定するのではなく、すべてのリクエストの応答時間をテストすることがいかに重要であるかについて少し明確にしましょう。



検索クエリの応答時間のパーセンタイル


デフォルトでは、 luceneutilキットのユーティリティは平均応答時間を測定しますが、非常に興味深い極端な値は破棄します。 これは、これらのユーティリティがアルゴリズムとそれらに加えられた変更の有効性をテストするように設計されているためです。具体的には、オペレーティングシステム、ディスクサブシステム、ガベージコレクタなどのレベルでの外部遅延によるランダムな逸脱を無視します



しかし、実際の検索アプリケーションにとって本当に重要なのは、すべての検索クエリの合計応答時間です。 検索は基本的にインタラクティブなプロセスです。ユーザーは座って検索結果が返されるのを待ってから、リンクをクリックします。 リクエストの1%でも多くの時間がかかる場合、これはすでに深刻な問題です! ユーザーは短気で、すぐに競合他社に移動します。



したがって、lucenutilを変更して、ロードクライアント( sendTasks.py )を個別のモジュールに割り当てることで、すべてのリクエストの応答時間を節約しました。 応答時間グラフをプロットするためのスクリプト( loadGraph.pyおよびresponseTimeGraph.py )も同様です。 直接実行するresponseTimeTests.pyスクリプトも変更され、負荷が増加する(要求/秒)一連のテストが実行され、負荷がサーバーのパフォーマンスを超え始めると自動的にテストが停止します。 さらに、このアプローチにより、平均化された指標から外挿するのではなく、実サーバーのパフォーマンスを測定できます。



実際のリクエストを送信する時間の最も正確なシミュレーションのために、クライアントはポアソン分布に従ってそれらを送信します。 テストスクリプトは1つのスレッドで動作します。1秒あたり200リクエストの速度でリクエストを送信し、何らかの理由でサーバーが5秒間フリーズすると、リクエストキューは1000になります。残念ながら、多くの負荷テストは異なる動作をし、エミュレートされたクライアントごとに個別のクライアントストリームを開始します。



クライアントは(sshを介して)別のマシンで動作しますが、これは重要なポイントです。これは、Luceneサーバー(JVMだけでなく)のパフォーマンスが定期的に低下するため(スワップが発生するなど)、ロードクライアントの動作が遅くなり、結果が歪む可能性があるためです。 理想的には、クライアントは専用マシンで実行され、一時停止は発生しません。 さらに、クライアントでPythonガベージコレクターが無効になり、その悪影響を排除します。



ウィキペディアでのテスト


Zingをテストするために、組み込みのフィールドと用語ベクトルを含め、サイズが約1KBの3330万のドキュメントを表す28.78 GBのプレーンテキストのボリュームを持つ、2012年5月時点の英語版ウィキペディアの完全なデータベースのインデックスを作成しました。 これにより、 FastVectorHighlighter



クラスを使用して結果を強調表示できます。 その結果、78 GBのインデックスが取得されました。 各テストで、サーバーは完全なインデックスをRAMDirectory



ロードし、その後、クライアントは500の最も重大なもの(ドキュメント内の最も一般的な用語)のリストから要求を送信します。 同時に、サーバーは1秒あたり約100ドキュメント(〜100 Kb / s)の速度でドキュメント( updateDocument



)のupdateDocument



updateDocument



ます。



各テストは1時間以内に実行され、ウォームアップに必要な最初の5分間はアカウンティングから除外されました。 ヒープの最大量は140 GB( -Xmx 140G



)でした。 基本レベルのパフォーマンスのために、最大ヒープ容量が4 GBのMMapDirectory



もテストしMMapDirectory



。 マシンには32個のプロセッサコア(64個のハイパースレッディングが有効)と512 GBのRAMがあり、サーバーは40個のスレッドで動作するように構成されています。



50(最小)から275(非常に大きい)までのさまざまなレベルの負荷(要求/秒)をテストし、さまざまな構成の応答時間の百分位数を示すグラフをプロットしました。 デフォルトでは、パラレルOracle GCの動作はひどく遅い(メモリをクリアするのに数十秒)ため、結果のレポートには含めませんでした。 新しいG1コレクターは、起動速度(競合するCMSコレクターを使用して900秒とは異なり、 RAMDirectory



にインデックスをロードするのに6時間かかりました)と、操作中に100秒を超える遅延が発生したため、さらに遅くなりましたまた、レポートには結果を含めませんでした(G1は大きなヒープで動作するように配置されているため、これは驚きでした)。 したがって、3つの構成をテストしましたMMapDirectory



デフォルト設定で、 MMapDirectory



クラスを基本レベルとして使用し、CMSとZingはRAMDirectory



クラスを使用します。



最小負荷(50リクエスト/秒)で、Zingは最悪の場合でも最小の応答時間を提供する良好なパフォーマンスを示しましたが、CMSはMMapDirectory



を使用している場合でも、十分に多くの場合にかなり長い応答時間を示しました:



画像



各構成の飽和限界を推定するために、99%のケースとさまざまな負荷レベルの応答時間を示すグラフを作成しました。



画像



このグラフから、 CMS + MMa



p CMS + MMa



場合、ピークパフォーマンスは100〜150リクエスト/秒のレベルに落ち、 RAMDirectory



を使用するRAMDirectory



、このピークはRAMDirectory



レベルに落ちると結論付けることができます。リクエスト/秒 これは驚くべきパフォーマンスの向上です! 平均応答時間を測定すると、 RAMDirectory



MMapDirectory



パフォーマンスの違いMMapDirectory



ほとんど目立たないため、この結果はさらに興味深いものです。



同じグラフを作成しますが、 CMS + MMapDirectory



結果は表示せず、275リクエスト/秒の負荷の結果も削除します(明らかに機器の能力を超えているため):



画像



99%パーセンタイルの場合、Zingのパフォーマンスは安定したままですが、CMSは100リクエスト/秒の負荷で始まる長い応答時間を示し始めます。 225リクエスト/秒の負荷を持つインジケーターを見てみましょう。これは飽和限界に最も近く、CMSとZingとともにRAMDirectory



を使用する場合です。



画像



一時停止に費やされる時間は、すでに50リクエスト/秒の負荷よりも大幅に長くなっています。すでに95%のパーセンタイルから始まって、応答時間が長くなりすぎています:4479ミリ秒以上。



Zingは動作します!


これらのテストは、Zingガベージコレクターを使用する場合、アプリケーションに140 GBのヒープが割り当てられ、Luceneインデックスの容量が78 GBでRAMDirectory



完全にロードされると、極端な負荷でも非常に短い応答時間が達成されることをRAMDirectory



ます。 さらに、1秒あたりの要求数で測定されるアプリケーションのパフォーマンスも大幅に向上し(検討された例では約2回)、Zingを実行している大きなインデックスでもRAMDirectory



を安全に使用できます。



最も注目に値するのは、Azulが最近、開発およびテストで使用するためのオープンソース開発者向けのJVM Zingの可用性を発表したことです。



All Articles