Solr-8.11.0における高CPU使用率

トピック作成者:ks-solruserml-bot (2024/06/20 15:32 投稿)
8
CloseClose

(The bot translated the original post https://lists.apache.org/thread/66rp8djgsgl5t8kpf6zl7ljjscdnvdzh into Japanese and reposted it under Apache License 2.0. The copyright of posted content is held by the original poster.)

こんにちは、

Solr-6.5.1からSolr-8.11.0への移行を試みており、以下がインストールの詳細です。

サーバー:32 CPU、521 GBのEC2インスタンス
ストレージ:EBSボリューム。General Purpose SSD (gp3)、3000/5000 IOPS
Ubuntu:Ubuntu 20.04.3 LTS
Java:openjdk 11.0.14
SolrCloud:12シャード、合計4+ TBのインデックス。各ノードの最大メモリ制限は30GB。
SolrのGC設定:G1GC
Solrクエリのタイムアウト:5分

テスト中に高いCPU使用率が観測され、ワイルドカードクエリを含む一部のクエリがタイムアウトしていることがわかりました。これらのクエリはSolr-6.5.1で完全に実行されています。GC設定のいくつかのパラメータを調整した後、CPU使用率は下がりましたが、Solr-6.5.1と比較してまだ高く、ワイルドカードクエリを含む一部のクエリが失敗しています。

ご提案をお願いします。

よろしくお願いします。
Modassar

返信投稿者:ks-solruserml-bot (2024/06/20 15:32 投稿)

CPU時間がどこで消費されているかの詳細な情報を提供できますか?JFRプロファイルを見たり、いくつかのjstackを収集してボトルネックがどこにあるかを確認してみてください。

返信投稿者:ks-solruserml-bot (2024/06/20 15:32 投稿)

お使いのシステムでクエリ時のマルチタームシノニムまたはWordDelimiter[Graph]Filterを使用していますか?これらは「グラフフレーズ」クエリをトリガーする可能性があり、Solr 8.11と6.5では処理がかなり異なることに注意が必要です(直接的にパフォーマンスの問題を引き起こす可能性は低いですが、パフォーマンスの違いを説明する要因となる可能性があります)。もしこれらを使用していない場合、このメッセージの残りの部分はおそらく関係ありません。

さらに証拠を収集する際に注意するべき点が1つあります(Mike Drobさんの提案に加えて):Solr 6.5から「グラフフレーズ」クエリに対してスパンクエリが使用されるようになりました(LUCENE-7699)、しかしSolrではこのフレーズクエリが完全に無視されていました(バグ)が、7.6(SOLR-12243)で修正されました。複雑なフレーズクエリを完全に無視することで、6.5では遅延とCPU負荷が大幅に低減しました。

7.6からはこれらのクエリに再度注意が払われるようになりましたが(SOLR-12243)、ps(フレーズスロップ)が0より大きい場合はフレーズクエリの完全列挙アプローチに戻ります(LUCENE-8531)。

edismaxを使用している場合に調整できるいくつかのパラメータ:

  1. pf=を設定して(フレーズフィールドに空の文字列を設定して)、暗黙のフレーズクエリ構築を無効にします。これにより、問題のパフォーマンスがフレーズクエリに関連しているかどうかがわかります。
  2. ps=0を設定して(フレーズスロップを0に設定して)、スパンクエリの構築を許可します。これは一般的に非スパンクエリアプローチよりも効率的です(基本的にはLUCENE-8531によって導入された変更が関係しなくなります)。余談ですが、ps=0のスパンクエリの特別なケースはLucene 9.0で削除されます(Solr 9.0では削除されますが、この問題には直接関係ありません)。

Michael

返信投稿者:ks-solruserml-bot (2024/06/20 15:32 投稿)

"vmstat 5 -w" コマンドを数分間実行し、問題が発生している間の出力を取得すると、ボトルネックを特定するのに役立ちます。ターミナルは非常に広いものを使用するのが最適です — たとえば132列以上です。マイクが間違っているとは言いませんが、別のデータポイントを見て共有できると思います。

ワイルドカードクエリは、カーディナリティが非常に低いフィールドでない限り、非常に効率が悪い傾向があります。おそらく、百万または十億ものユニークなトークンを持つであろう、最も高いカーディナリティのフィールドでそれらを実行しているのではないでしょうか。

ここで疑っているのは、「ディスクキャッシングのための十分なシステムメモリが不足している」ということです... つまり、6.5.1では何とかうまく処理できていたものの、その後の変更で少し変わってしまい、今ではパフォーマンスの問題が発生しているということです。

各マシンには、12シャードの完全なコピー(合計4TB)があり、512GBのメモリを搭載していますか? もしそうなら、各サーバーにさらに多くのメモリを搭載する必要があるかもしれません。

https://cwiki.apache.org/confluence/display/solr/SolrPerformanceProblems

(このWikiページを書いたのは私ですので、もし間違いがあれば私の責任です)

ありがとうございます。
Shawn

返信投稿者:ks-solruserml-bot (2024/06/20 15:33 投稿)

皆さん、提案ありがとうございます。

プロファイリングを試して、ボトルネックを特定してみます。

以下の例外が発生していますが、これはワイルドカードクエリのマルチタームフィールド展開に起因する可能性があると理解しています。もし誤っていたら訂正してください。
ドキュメント値を反復処理するのに時間がかかりすぎました。

WordDelimiterGraphFilter は使用していませんが、WordDelimiterFilter が使用されており、その設定は以下の通りです。WordDelimiterFilter は非推奨ですので、次のステップで削除します。

<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1"
generateNumberParts="1" catenateWords="1" catenateNumbers="1"
catenateAll="1" splitOnCaseChange="1" preserveOriginal="1"/>

ワイルドカードクエリはテキストデータに対して実行され、はい、ワイルドカードクエリの可能な展開が非常に多数あります。
すべての12シャードが単一のマシンにあり、メモリは521GBで、各シャードは SOLR_JAVA_MEM="-Xmx30g" で起動しています。したがって、521GBのメモリはすべての12シャードで共有されています。

以下はキャッシュの設定です。

<filterCache class="solr.FastLRUCache" size="128" initialSize="128" autowarmCount="0"/>
<queryResultCache class="solr.LRUCache" size="128" initialSize="128" autowarmCount="0"/>
<documentCache class="solr.LRUCache" size="128" initialSize="128" autowarmCount="0"/>

ありがとうございます。
Modassar

返信投稿者:ks-solruserml-bot (2024/06/20 15:33 投稿)

私の最初の考えが正しいと信じています — 4TBのインデックスデータを処理するには、もっと多くのメモリが必要です。私が言っているのは、SolrではなくOSに利用可能なメモリのことです。これはおそらく6.xでも問題であったでしょうが、Solrをアップグレードすると、不十分なメモリが以前よりも顕著な問題になる場合があります。

試してみることができるのは、ヒープサイズを31gに増やすことです。実際に必要な証拠が見えるまでは、それ以上の増加はお勧めしません。32GBのヒープサイズからJavaは64ビットポインタに切り替わりますし、本当に必要な場合は48GB程度になる可能性があります。実際、31GBのヒープにしても性能が向上することは期待していませんが... もし改善されるなら、それは他の問題にも直面している可能性があります — ウィキページで言及されているもう一つの主要な問題、つまりヒープサイズが小さすぎることです。これにより、Javaがアプリケーションを実行するよりもゴミの収集に時間を費やすことになります。

私は、古いバージョンではSolrがWordDelimiterFilterやWordDelimiterGraphFilterの全機能を利用していないことについて、マイケルが言及した内容を知りませんでした。これらのフィルタは一般にカーディナリティを大幅に増加させ、最近のSolrバージョンではヒープメモリの利用も増加するようです。

ありがとうございます。
Shawn

返信投稿者:ks-solruserml-bot (2024/06/20 15:33 投稿)

ショーンの意見に同意します。理想的には、OSに対してもっと多くのメモリが欲しいと思います。

ただし、送っていただいたWordDelimiterFilterの設定は、私の疑念が正しいことを示しています。つまり、"graph phrase"の問題が6.5と8.11の違いを説明する可能性が高いということです。クエリ実行時、WordDelimiterFilter(そして同様にWordDelimiterGraphFilterも)は両方ともpf(フレーズフィールド)で "graph phrase" の動作を引き起こしますが、6.5ではこれらが完全に無視されていたとほぼ確信しています。

そのため、今後の進展に向けて6.5を比較対象とすることはあまり役立たないでしょう。なぜなら、6.5の「より良いパフォーマンス」は、実際にはpfの "graph phrase" クエリが一切実行されなかったバグの結果だったからです。

2021年6月のこのメーリングリストのやり取り[1]が役立つ/関連するはずです。(また、お使いの問題に関しては、WordDelimiterFilterとWordDelimiterGraphFilterの間に実質的な違いはありませんので、その点についても注意してください。)

[1] https://lists.apache.org/thread/kbjgztckqdody9859knq05swvx5xj20f

返信投稿者:ks-solruserml-bot (2024/06/20 15:33 投稿)

返信ありがとうございます。

はい、物理メモリを追加することは助けになりますが、現在の状況では使用しているGC設定さえも最適なものではないかもしれません。GC設定に関するいくつかの提案をお願いできますか?
また、私たちはさらにシャードを追加し、異なる小さなEC2インスタンスでシャードごとにより小さなインデックスを作成する計画です。メモリの要件と検索パフォーマンスを評価します。

さらに一点付け加えますと、ワイルドカードを含まないクエリ(例:ブールクエリや10000個のIDをORで結合したクエリ)も遅くなり、CPUも多く消費し、最終的にはより多くの時間がかかるようになっています。これは多数のGC停止が原因だと理解しており、GC設定を調整すればCPUの利用率が減少するはずです。

pfを空文字列に設定してパフォーマンスを確認し、また「enableGraphQueries」の設定を確認します。また、私たちのニーズに応じて少ないトークンを生成するカスタムワードデリミタフィルターは、検索パフォーマンスの向上に役立つでしょうか?

ありがとう、
Modassar

返信投稿者:ks-solruserml-bot (2024/06/20 15:34 投稿)

Solr 8.xにデフォルトで搭載されているGC設定はすでに非常に良好です。免責事項として、これらの設定は私が激しいテスト作業の後に考案したものと非常に似ています。

もし最近のJava 11またはOpenJDK 11のリリースを実行しており、テスト環境がある場合、Shenandoahを試すことができます。私のテストでは、このコレクターはGC停止活動において大きな違いをもたらすことがわかりましたが、スループットは確実に低下します。もしインデックス速度が十分に速い場合、以下の設定をsolr.in.shファイルに試してみてください:

GC_TUNE=" \
  -XX:+UseShenandoahGC \
  -XX:+AlwaysPreTouch \
  -XX:+PerfDisableSharedMem \
  -XX:+ParallelRefProcEnabled \
  -XX:+UseStringDeduplication \
  -XX:ParallelGCThreads=2 \
  -XX:+UseNUMA

UseNUMAは、サーバーに複数のNUMAノードがある場合にのみ効果があります。ただし、NUMAがない場合でも何も問題を引き起こしません。

私はインデックス速度とスループットを言及しましたが、Shenandoahを使用するとインデックス速度が低下することが分かりました。私の環境では、G1を使用した場合の約8分で完全な再インデックスができ、Shenandoahを使用した場合は約9分かかります。GCの分析によれば、より多くの小さなGC停止があり、総合的な停止時間は少し低下しています。しかし、Shenandoahのテストを共同で行ったパートナー(私のより大きなインデックスを持っています)は、Shenandoahでの再インデックスが完了しなかったと報告していますので、本番環境に展開する前にテストシステムで試してみることをお勧めします。

私のShenandoahのテストはOpenJDK 11.0.3で行いましたが、現在のサーバーには11.0.14があり、理論的にははるかに安定しているはずです。

また、いくつかの良いCMS(Concurrent Mark-Sweep)の設定も考案しましたが、CMSコレクターは非推奨になっていると思いますが、具体的にどのJavaバージョンで廃止されるかはわかりません。

https://cwiki.apache.org/confluence/display/solr/ShawnHeisey

ありがとう、
Shawn

トピックへ返信するには、ログインが必要です。

KandaSearch

Copyright © 2006-2024 RONDHUIT Co, Ltd. All Rights Reserved.

投稿の削除

この投稿を削除します。よろしいですか?