ElasticSearchのfield data cacheについて
ElasticSearchをしばらく運用してみて、いくつかノウハウがたまってきたので残しておきます。
Solrを使う事が多かったので最初は慣れなかったんですが、公式のドキュメントがSolrより充実しているしクエリがJsonベースで組みやすいので結構使いやすい気がしてきました。
今回はfield data cacheについてです。余裕ある人は公式サイト見た方が色々詳しいと思います。
https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-fielddata.html
field data cacheとは
ElasticSearchでは、各fieldのデータをメモリに載せることで検索を高速化しています。これをfield data cacheと呼びます。SortやAggregation(集計)を高速に行うためには必須と言って良いと思います。
field data cacheのサイズについて
field data cacheはデフォルトでは無制限でメモリに乗るため、OutOfMemoryErrorが発生することがあります。よって、必要に応じてfield cacheに使用可能なメモリのサイズを調整します。
以下は使用可能なメモリをHEAP_SIZEの75%に設定する例です。
/etc/elasticsearch/elasticsearch.yml
indices.fielddata.cache.size: 75%
Warmerクエリについて
fieldデータをメモリに乗せる処理はインデックス再構築後1回目のクエリが投げられた時に行われるのですが、その処理は非常に重いためそのままでは1回目のクエリだけ結果がなかなか返らなくなってしまいます。
そんな時はWarmerクエリをインデックスに設定しておけば、インデックス再構築後に自動でクエリを発行してfield data cacheを作成してくれます。
参考URL:http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-warmers.html
curl -XPUT localhost:9200/testindex/_warmer/warmer_1 -d '{ "query" : { "match_all" : {} }, "aggs" : { "aggs_1" : { "terms" : { "field" : "field" } } } }'
doc_valuesについて
マッピングの際に各フィールドにdoc_values:trueを設定しておくと、field data cacheをメモリではなくディスクに乗せることができます。メモリに乗せる場合よりも20%程低速になりますが、ヒープメモリに影響されなくなるのでメモリを増やせない場合に有効です。設定後は再インデックスが必要です。
個人的にはデータ量が多い場合はこっちを使った方が良いと思います。
参考URL : https://www.elastic.co/blog/disk-based-field-data-a-k-a-doc-values
まとめ
- 20%の速度低下を許容できるならdoc_valuesを使ったほうが安定する
- doc_valuesを使わない場合は、OutOfMemoryErrorを避けるためにindices.fielddata.cache.sizeを設定した方が良い(75%がおすすめ)
- Warmerを設定してcache作成を自動で行えるようにしておくこと(インデックス再構築後に自分で空クエリ投げても良い)
以上です。doc_values便利なのでオススメです。