起こった問題
Solr5.5にして以降、Swap memoryをかなり消費して悩まされる日々が続く。結果として、Solr5.5と同時にjava8を使い始めており、java8から変更になった Metaspace領域 が、許す限り使ってしまう設定になっていたことが原因だった。始めのうちはSolr周りの設定やJVMのヒープ内における設定見直しに注力してしまい、ここに至るまで時間が空いてしまった。java系で動くミドルウェアを導入・運用する点において、JVMの仕樣・設定ポイントを理解しておくのは大切だねと思ったしだい。
初期設定(solr.in.sh)と調査
solr5系を基本の手順に従ってインストールすると作成される"solr.in.sh" 内のGC_TUNEにある内容は以下の通りで、JVMのGCにおけるアルゴリズムやその周辺の設定が入っている。
GC_TUNE="-XX:NewRatio=3 \
-XX:SurvivorRatio=4 \
-XX:TargetSurvivorRatio=90 \
-XX:MaxTenuringThreshold=8 \
-XX:+UseConcMarkSweepGC \
-XX:+UseParNewGC \
-XX:ConcGCThreads=4 -XX:ParallelGCThreads=4 \
-XX:+CMSScavengeBeforeRemark \
-XX:PretenureSizeThreshold=64m \
-XX:+UseCMSInitiatingOccupancyOnly \
-XX:CMSInitiatingOccupancyFraction=50 \
-XX:CMSMaxAbortablePrecleanTime=6000 \
-XX:+CMSParallelRemarkEnabled \
-XX:+ParallelRefProcEnabled"
同じくsolr.in.sh内でGC_LOG_OPTSを有効にして、GCのログを取得、そのログを元にGC easyを使って、Full GCなどの頻度を調べていた。NewRatioやSurvivorRatioの設定を変更して、ある一定は効果はあるが根本的にswapの使用状況を改善できず。
Java8での変更点を調べる
そもそも、これまで使っていた環境がJava7系が主だったので、Java8にしたことに何か起因するのではという疑問を持った。そして、こちらの記事Java8のHotSpotVMからPermanent領域が消えた理由とその影響にたどり着き、Java8におけるMetaspace領域のデフォルト設定値が怪しいと確信に至りました。
MaxMetaspaceSizeの追加後
solr.in.shのGC_TUNEへ-XX:MaxMetaspaceSize=256M を設定し、Solrをリスタートしてみました。
設定した時点から数日間、これまでのような大きなswapの発生は見られなくなりました。ひとまず安心でしょうか。
終わりに
SolrやJVMの調査をしていて、最終的にJava8における変更点にやっとたどり着きました。Java上で動くミドルウェアも多いので、JVMの特性はよく理解したいところでした。Metaspaceが無尽蔵に近い領域を使用できることにもう少し早く気付けていれば、悩ましい日々が短縮できたのに。