遅いGCが高いヒープ使用量を引き起こしています

トピック作成者:ks-solruserml-bot (2024/06/09 21:16 投稿)
7
CloseClose

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

私たちは8.3.1から8.8.1へのアップグレードを試みていますが、リリース前のテストでいくつかのパフォーマンスの問題が発生しています。GCログの調査によると、可能な原因はこちらにあるかもしれません:

8.3.1のグラフ: https://imgur.com/a/ZM9wdob
8.8.1のグラフ: https://imgur.com/a/UzMinwJ

ここでのテストサイクルは、リクエストを2分間行い、リクエストを行わない2分間、再びリクエストを2分間行います。8.3.1では、比較的一貫したヒープ使用量と、比較的高速かつ一貫したGCの期間が得られます。しかし、8.8では、最初のリクエストサイクルでヒープ使用量が着実に増加し、GCの期間の1つで大きなスパイクが見られます。

この広いパターンが繰り返され、8.8では時に1回以上の遅いGC操作が、私がテストするたびに信頼性のある結果として現れます。これを引き起こす可能性がある、設定が誤って構成されているか、それともバグか、どちらかがあるでしょうか?

ありがとう、
Dominic

返信投稿者:ks-solruserml-bot (2024/06/09 21:16 投稿)

ヒープが小さい場合、GCに12秒かかるのは非常に過剰です。そのヒープのサイズではそんなに時間がかかるべきではありません。もしヒープが8GB以上であれば、それが起こることを理解できます。フルGCが発生する場合の一般的な解決策は、JavaがフルGCではなくより高速な世代固有のコレクションを選択しやすくするために、ヒープサイズを増やすことです。

私の推奨は、Javaのバージョンをアップグレードするか変更することです。もし同じJavaバージョンであると言われたら、2つのバージョンの動作に違いがあり、新しいバージョンが古いバージョンでは発生しないJavaのGCのバグを引き起こす可能性があるかもしれません。最新のJava 8は大丈夫です。後のJavaバージョンを選択する場合、それが機能するかどうかは、Solrバージョンがどれほど古いかによります。LTS Javaバージョンの最新リリース(8、11、14、および17)にこだわるべきです。以前はOracle Javaをお勧めしていましたが、ライセンスが変更されてほとんどの人が支払わなければならなくなったため、無料の代替品を選択する方が良いでしょう。OpenJDKが優れたオプションです。IBMのJavaやそれに由来するベンダーを避けてください。IBMのJavaは既知の問題を引き起こします。

Solrが現在搭載しているデフォルトのG1ではなく、GCをCMSに変更することも試してみることができます。

https://cwiki.apache.org/confluence/display/solr/shawnheisey#ShawnHeisey-CMS(ConcurrentMarkSweep)Collector

このウィキページでは、私が独自のイニシャライザスクリプトを持っていたため、環境変数がJVM_OPTSとして示されています。当時、Solrにはイニシャライザスクリプトがなかったので、そのように書きました。solr.in.shまたはsolr.in.cmdで使用するには、GC_TUNEに変更する必要があると思います。近いうちに、現代のSolrバージョンを反映するためにそれを変更する予定です。

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

返信投稿者:ks-solruserml-bot (2024/06/09 21:17 投稿)

JVMの設定(ヒープとGC)はどのようになっていますか?

wunder
Walter Underwood
wunder@wunderwood.org
http://observer.wunderwood.org/ (私のブログ)

返信投稿者:ks-solruserml-bot (2024/06/09 21:17 投稿)

ありがとうございます!

確かに、どちらも同じJava(OpenJDK 11)を使用しています。バージョンを14にアップグレードしてみましたが、ヒープは少し小さくなりましたが、依然として大きな(10秒以上)のGCの期間が発生しています。

残念ながら、CMSへの切り替えがうまくいっていません。

返信投稿者:ks-solruserml-bot (2024/06/09 21:17 投稿)

私の知る限り、これらはインストールからデフォルトで提供される設定です:

java -server -Xmx1944m -XX:+UseG1GC -XX:+PerfDisableSharedMem
-XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=250 -XX:+UseLargePages
-XX:+AlwaysPreTouch -XX:+ExplicitGCInvokesConcurrent
-Xlog:gc*:file=/srv/solr/logs/solr_gc.log:time,uptime:filecount=9,filesize=20M
-Dsolr.jetty.inetaccess.includes= -Dsolr.jetty.inetaccess.excludes=
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=18983
-Dcom.sun.management.jmxremote.rmi.port=18983 -Dsolr.log.dir=/srv/solr/logs
-Djetty.port=8983 -DSTOP.PORT=7983 -DSTOP.KEY=solrrocks -Duser.timezone=UTC
-XX:-OmitStackTraceInFastThrow -Djetty.home=/usr/local/solr/server
-Dsolr.solr.home=/srv/solr/data -Dsolr.data.home=
-Dsolr.install.dir=/usr/local/solr
-Dsolr.default.confdir=/usr/local/solr/server/solr/configsets/_default/conf
-Dlog4j.configurationFile=/srv/solr/log4j2.xml
-Dsolr.disable.shardsWhitelist=true -Xss256k -jar start.jar --module=http
返信投稿者:ks-solruserml-bot (2024/06/09 21:17 投稿)

CMSではどのような結果が得られましたか?

まず試してみるべきことがあります。前提として、十分なメモリがインストールされていると仮定して、最大ヒープサイズを増やすことです。利用可能な余裕が十分にある場合、Javaは世代固有のコレクターを使用する可能性が高くなります。これらのコレクターはフルGCよりもはるかに高速であり、いくつかのフェーズではアプリ(この場合はSolr)を実行中に一時停止しません。

少なくとも11u9のバージョンを実行している場合、Javaの新しいコレクターであるShenandoahにアクセスできます。私自身のSolrインストールでShenandoahを有効にしました。

私はShenandoahがJavaバージョン11より新しいバージョンを必要とすると考えていましたので、まだ試していませんでした。以下は、/etc/default/solr.in.sh に設定した内容です:

GC_TUNE=" -XX:+AlwaysPreTouch -XX:+UseNUMA -XX:+UseShenandoahGC -XX:+ParallelRefProcEnabled -XX:ParallelGCThreads=6 "

私のサーバーはNUMAハードウェアですので、そのオプションを含めました。CPUコアが12個あるため、JavaにGC用に6つのスレッドを使用するように指示しました。おそらくParallelRefProcEnabledを含める必要はありませんが、Javaの後のバージョンでデフォルトが変更される可能性があるため、明示的に指定するのが好きです。

Shenandoahを試してみることをお勧めします。これは現在利用可能な最高の低遅延オプションであるとされています。また、メモリが十分にある場合は、ヒープを大きくすることも検討してください。キャッシュ目的の未割り当てメモリが十分にあることを確認してください。Solrのヒープでマシンのすべてのメモリを使用することは避けたいです。

もし私のインストールがGCを実行し始めたら(ヒープが実際に必要なものよりもはるかに大きいです)、Shenandoahが有益であるかどうかがわかるかもしれません。

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

返信投稿者:ks-solruserml-bot (2024/06/09 21:18 投稿)

追記:

興味深いことに、Shenandoahはアクティビティが非常に少なく、通常GCが必要ない場合でも、5分ごとにコレクションを実行するようです。

15分間の実行後、小さなログをgceasyにかけてみました:

https://www.dropbox.com/s/0ivey9lrnrzpim1/gceasy-shenandoah.png?dl=0

ご覧の通り、現在のヒープサイズは非常に小さいです。GCの停止時間も非常に短いです。このSolrインストールは、私のメールサーバー、具体的にはdovecotのためのものです。

また、Java 11で利用可能なZGCという別のコレクタにも出会いました。Shenandoahについて知っているよりもさらに少ない知識しかありません。

興味深い読み物があります:

https://blogs.oracle.com/javamagazine/understanding-the-jdks-new-superfast-garbage-collectors

テラバイトサイズのヒープでもほぼゼロに近い停止時間を約束する商用JVMが存在します。価格については全く分かりませんが、おそらく非常に高価だと思います:

https://www.azul.com/products/prime/

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

返信投稿者:ks-solruserml-bot (2024/06/09 21:18 投稿)

はい、大きなヒープと世代別のコレクタを使用してください。CMSを使用した際は、8GBのヒープに2GBの短命世代(短期間で消えるオブジェクトを管理する領域)を持っていました。検索リクエストを処理するためのほとんどのアロケーション(メモリ割り当て)はリクエストの終了時に解放されるため、Solrは大量の新しい世代スペースを利用できます。

Solr 8.6、Java 11、G1GCを使用する現在では、すべてのJVMで16GBに移行しました。8GBの際には過度のGC問題が発生していました。

私たちのクラスタではファセットを行いませんが、重い検索処理を行っています。最大のクラスタは6000万件のドキュメント、8つのシャード、平均クエリ長は25用語です。36個のCPUを持つEC2インスタンスを使用しています。

-Xms16g
-Xmx16g
-Xss256k
-XX:+AlwaysPreTouch
-XX:+ExplicitGCInvokesConcurrent
-XX:+ParallelRefProcEnabled
-XX:+PerfDisableSharedMem
-XX:+UseG1GC
-XX:+UseLargePages
-XX:-OmitStackTraceInFastThrow
-XX:MaxGCPauseMillis=250

wunder
Walter Underwood
wunder@wunderwood.org
http://observer.wunderwood.org/ (私のブログ)

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

KandaSearch

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

投稿の削除

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