|
| 1 | +[[index-modules-shard-query-cache]] |
| 2 | +== Shard query cache |
| 3 | + |
| 4 | +coming[1.4.0] |
| 5 | + |
| 6 | +When a search request is run against an index or against many indices, each |
| 7 | +involved shard executes the search locally and returns its local results to |
| 8 | +the _coordinating node_, which combines these shard-level results into a |
| 9 | +``global'' result set. |
| 10 | + |
| 11 | +The shard-level query cache module caches the local results on each shard. |
| 12 | +This allows frequently used (and potentially heavy) search requests to return |
| 13 | +results almost instantly. The query cache is a very good fit for the logging |
| 14 | +use case, where only the most recent index is being actively updated -- |
| 15 | +results from older indices will be served directly from the cache. |
| 16 | + |
| 17 | +[IMPORTANT] |
| 18 | +================================== |
| 19 | +
|
| 20 | +For now, the query cache will only only cache the results of search requests |
| 21 | +where <<count,`?search_type=count`>>, so it will not cache `hits`, |
| 22 | +but it will cache `hits.total`, <<search-aggregations,aggregations>>, and |
| 23 | +<<search-suggesters,suggestions>>. |
| 24 | +
|
| 25 | +Queries that use `now` (see <<date-math>>) cannot be cached. |
| 26 | +================================== |
| 27 | + |
| 28 | +[float] |
| 29 | +=== Cache invalidation |
| 30 | + |
| 31 | +The cache is smart -- it keeps the same _near real-time_ promise as uncached |
| 32 | +search. |
| 33 | + |
| 34 | +Cached results are invalidated automatically whenever the shard refreshes, but |
| 35 | +only if the data in the shard has actually changed. In other words, you will |
| 36 | +always get the same results from the cache as you would for an uncached search |
| 37 | +request. |
| 38 | + |
| 39 | +The longer the refresh interval, the longer that cached entries will remain |
| 40 | +valid. If the cache is full, the least recently used cache keys will be |
| 41 | +evicted. |
| 42 | + |
| 43 | +The cache can be expired manually with the <<indices-clearcache,`clear-cache` API>>: |
| 44 | + |
| 45 | +[source,json] |
| 46 | +------------------------ |
| 47 | +curl -XPOST 'localhost:9200/kimchy,elasticsearch/_cache/clear?query_cache=true' |
| 48 | +------------------------ |
| 49 | + |
| 50 | +[float] |
| 51 | +=== Enabling caching by default |
| 52 | + |
| 53 | +The cache is not enabled by default, but can be enabled when creating a new |
| 54 | +index as follows: |
| 55 | + |
| 56 | +[source,json] |
| 57 | +----------------------------- |
| 58 | +curl -XPUT localhost:9200/my_index -d' |
| 59 | +{ |
| 60 | + "settings": { |
| 61 | + "index.cache.query.enable": true |
| 62 | + } |
| 63 | +} |
| 64 | +' |
| 65 | +----------------------------- |
| 66 | + |
| 67 | +It can also be enabled or disabled dynamically on an existing index with the |
| 68 | +<<indices-update-settings,`update-settings`>> API: |
| 69 | + |
| 70 | +[source,json] |
| 71 | +----------------------------- |
| 72 | +curl -XPUT localhost:9200/my_index/_settings -d' |
| 73 | +{ "index.cache.query.enable": true } |
| 74 | +' |
| 75 | +----------------------------- |
| 76 | + |
| 77 | +[float] |
| 78 | +=== Enabling caching per request |
| 79 | + |
| 80 | +The `query_cache` query-string parameter can be used to enable or disable |
| 81 | +caching on a *per-query* basis. If set, it overrides the index-level setting: |
| 82 | + |
| 83 | +[source,json] |
| 84 | +----------------------------- |
| 85 | +curl localhost:9200/my_index/_search?search_type=count&query_cache=true -d' |
| 86 | +{ |
| 87 | + "aggs": { |
| 88 | + "popular_colors": { |
| 89 | + "terms": { |
| 90 | + "field": "colors" |
| 91 | + } |
| 92 | + } |
| 93 | + } |
| 94 | +} |
| 95 | +' |
| 96 | +----------------------------- |
| 97 | + |
| 98 | +IMPORTANT: If your query uses a script whose result is not deterministic (e.g. |
| 99 | +it uses a random function or references the current time) you should set the |
| 100 | +`query_cache` flag to `false` to disable caching for that request. |
| 101 | + |
| 102 | +[float] |
| 103 | +=== Cache key |
| 104 | + |
| 105 | +The whole JSON body is used as the cache key. This means that if the JSON |
| 106 | +changes -- for instance if keys are output in a different order -- then the |
| 107 | +cache key will not be recognised. |
| 108 | + |
| 109 | +TIP: Most JSON libraries support a _canonical_ mode which ensures that JSON |
| 110 | +keys are always emitted in the same order. This canonical mode can be used in |
| 111 | +the application to ensure that a request is always serialized in the same way. |
| 112 | + |
| 113 | +[float] |
| 114 | +=== Cache settings |
| 115 | + |
| 116 | +The cache is managed at the node level, and has a default maximum size of `1%` |
| 117 | +of the heap. This can be changed in the `config/elasticsearch.yml` file with: |
| 118 | + |
| 119 | +[source,yaml] |
| 120 | +-------------------------------- |
| 121 | +indices.cache.query.size: 2% |
| 122 | +-------------------------------- |
| 123 | + |
| 124 | +Also, you can use the +indices.cache.query.expire+ setting to specify a TTL |
| 125 | +for cached results, but there should be no reason to do so. Remember that |
| 126 | +stale results are automatically invalidated when the index is refreshed. This |
| 127 | +setting is provided for completeness' sake only. |
| 128 | + |
| 129 | +[float] |
| 130 | +=== Monitoring cache usage |
| 131 | + |
| 132 | +The size of the cache (in bytes) and the number of evictions can be viewed |
| 133 | +by index, with the <<indices-stats,`indices-stats`>> API: |
| 134 | + |
| 135 | +[source,json] |
| 136 | +------------------------ |
| 137 | +curl -XPOST 'localhost:9200/_stats/query_cache?pretty&human' |
| 138 | +------------------------ |
| 139 | + |
| 140 | +or by node with the <<cluster-nodes-stats,`nodes-stats`>> API: |
| 141 | + |
| 142 | +[source,json] |
| 143 | +------------------------ |
| 144 | +curl -XPOST 'localhost:9200/_nodes/stats/indices/query_cache?pretty&human' |
| 145 | +------------------------ |
0 commit comments