Solr のキャッシュに関するお話

全国津々浦々の Solr ファンのみなさんこんにちわ、Solr おじさんです。
本日は Solr のキャッシュについてお話します。

Solr のキャッシュの種類

主に使うキャッシュの種類は FilterCache, DocumentCache, QueryResultCache の3つがあります。。DocumentCache, QueryResultCache は名前からわかる通りドキュメントのキャッシュと、クエリ結果のキャッシュ。

FilterCache は何をしているのか。これは、Solr の検索クエリの fq パラメーターで指定する、Filter Query の結果をキャッシュするものです。検索キーワードなどクエリごとに異なるであろう部分は q パラメーターで指定し、あまり変わらないもの、例えばユーザーごとに userId:1234 でフィルタするというようなある程度静的なものを fq で指定するとフィルタキャッシュがよく効くようになり、Solr からの応答時間が短くなります。

キャッシュが有効に使われているかどうかの確認

簡単に見るには管理画面からコアを選択し、Plusings/ Stats の項目でキャッシュを確認すれば OK です。
f:id:shawshank99:20170831115019p:plain

JMX を用いて監視することもできます。Solr には初めから JMX でキャッシュ項目等かなり多岐にわたる項目を監視できます。

監視する際は、JMX を使えるクライアントなら何でも良いのですが、今回は手軽に jconsole を使います。Solr が動いているマシンと同じマシン上で jconsole を立ち上げて、Solr にアタッチ。コアを指定して filterCache の項目を開くと状態が見れます。
f:id:shawshank99:20170831115037p:plain

さて見方ですが、hitrate と evictions あたりを見れば良いでしょう。それぞれヒット率と、追い出されたキャッシュエントリ数を表します。hitrate が低すぎたり evictions が多いと性能に影響をもたらしますし、一方で改善可能でもあります。inserts 等や size あたりも勘案した上でキャッシュサイズを指定しましょう。キャッシュサイズは solrconfig.xml で指定できます。

SoftCommit に騙されるな!

Solr には SoftCommit という機能があります。これは NRT (Near-Realtime) 検索のために利用されます。NRT 検索とは、ドキュメントをほぼリアルタイムに検索できる機能で、直前に追加されたドキュメントもこの機能のおかげで検索にマッチするようになります。SoftCommit が無い時代は HardCommit のタイミングを超えないとドキュメントが検索できませんでした。HardCommit はメモリ上に溜まったデータをストレージ書き込むのでコスト高、SoftCommit はメモリ内の処理で終わるのでコスト安、SoftCommit を毎秒行ってリアルタイム検索できるようにしよう!ひゃっほおおおう!と思うのが人の常ですが、これは罠なのでやってはいけません。

というのも、原因は Solr のキャッシュモデルにあります。Solr にはサーチャーという仕組みがあり、これは言わばある瞬間のインデクスデータと紐付いたものなのですが、FilterCache や DocumentCache はこのサーチャーに紐付いています。インデクスデータが更新されたらサーチャーは新しいものに切り替わり、従ってキャッシュも破棄されます。HardCommit はもちろんのこと、SoftCommit でもサーチャーは新しくなり、キャッシュが破棄されてしまいます。よってほぼキャッシュの恩恵は得られません。

HardCommit, SoftCommit のタイミングはどれくらいがベストなのか、というのは難問です。保持してるインデクス量や検索頻度などアプリケーションの性質にもよるので一概には言えませんが、少なくとも「更新頻度が高い環境下で HardCommit, SoftCommit を頻繁に行うと検索性能が低下する」ということは言えるでしょう。

ちなみにこの SoftCommit, 登場した時点では鳴り物入りで出た機能なのですが、最新の Solr (現在 6.6.0)ではデフォルトでは無効になっています。前述した性能問題を気にしてのことなのか、それとも HardCommit の処理が低負荷になったからなのか、理由はわかりませんがそういうことなのでそういうことなのでしょう。

autowarmCount に騙されるな!

さてもう一点。サーチャーが切り替わる時、古いサーチャーから新しいサーチャーにキャッシュ情報を移す autowarmCount という設定があります。これを使えば新しいサーチャーが生成された時も自動でキャッシュが蓄積されるので最高!という雰囲気になるのですが、これも罠なので迂闊に使ってはなりません。

autowarmCount は、古いキャッシュコンテナから新しいキャッシュコンテナにどれだけのキャッシュエントリをコピーするのか、その数を指定する、というものではありません。古いキャッシュコンテナの上位 autowarmCount 個のキャッシュが、新しいキャッシュコンテナ内に溜まるまでクエリを発行する、というものです。従って autowarmCount に 1024 とかを指定すると、サーチャーが立ち上がるたびに 1000 を超えるクエリが発行されるので性能的に死にます。キャッシュ用のデータを溜めるためのクエリなので当然これらのクエリはキャッシュの恩恵を受けられません。

というわけで autowarmCount は一見よさ気ではありますが、ちょっと設定をミスると「性能のために導入したキャッシュのウォームアップで性能的に死ぬ」という寓話みたいなことになるので注意しましょう。この autowarmCount は今も昔もデフォルト設定は 0 です。

まとめ

罠はあるけども Solr は基本的に賢くて良い子なのでもう少し愛情を注いであげましょう。

[改訂第3版]Apache Solr入門――オープンソース全文検索エンジン (Software Design plus)

[改訂第3版]Apache Solr入門――オープンソース全文検索エンジン (Software Design plus)