Javaパフォーマンスを読んでsolrのパフォーマンス改善を行った

- (4 min read)

業務で使っているSolrの検索クエリのレスポンスタイムがしきい値を超えたときのアラートが急増した。原因を調査しようにも知識が足らなすぎたのでJavaパフォーマンスを読んだ。

本書はJavaで開発されたアプリケーションのチューニングをするための本だ。そのためパフォーマンスとは何か、パフォーマンスについて語るときによく使われるスループットやレスポンスタイムといった用語の解説や正しい計測方法から解説される。今回のように既に特定のツール経由でパフォーマンスに関する通知を受けているときはその通知の定義に従う必要があるが、用語の定義を合わせておくのはとても正しい。

その後、Javaで利用できるパフォーマンスに関するツールの使い方、JITコンパイラの仕組み、ガーベージコレクションの仕組みについての解説がある。今回はこのあたりが問題解決のために役立った(個人的にはGCの仕組みが面白かった)
今回の事例では95パーセンタイルのレスポンスタイムが悪化しているわけではなく、レスポンスタイムが跳ねる頻度が増えたのでGCのタイミングに巻き込まれることが増えたのだろうとあたりを付けていた。実際書籍を参考にgc_logを解析したところ、YoungGCの発生頻度が2回/分だったのが20回/分に増えていた。また、当時利用していたGCアルゴリズムはCMS GCで、書籍によるとCMS GCではYoungGCでもアプリケーションスレッドがストップするとのことだった。
実際にYGCの頻度が急増したあたりに何か変更をしたかを調査してみると、それまでsolrクエリを発行する必要のなかった画面で2回facet queryをリクエストする変更をしていた。さらに運の悪いことに同じくらいに海外から同画面への悪意のあるリクエストが高頻度で発生するようになっていた。
結局、悪意のあるリクエストはアプリケーションに届く手前で遮断し、アラートは落ち着いた。また、別途solrクエリの発行回数を見直したりsolrとJavaのバージョンアップやGCアルゴリズムの変更を検討することとなった。

パフォーマンス改善は言語独自のチューニングはもちろんのこと、複合要因が絡んでくる(今回も修正した箇所はJavaとは関係なかった)ので難しいが、書籍で読んだ箇所が上手く利用できたので良かった。

なお、書籍ではその後にベストプラクティスやチューニング方法について記載されている。Javaアプリケーションのパフォーマンス改善を目指す場合は最も参照される箇所だと思う。