Elasticsearch использует три типа кэшей для повышения эффективности работы.
- Кэш запросов узлов
- Кэш данных шардов
- Кэш данных полей
Как они работают
- Кэш запросов узла хранит результаты запросов, используемых в контексте фильтра. Результаты удаляются по принципу наименьшего количества последних использований.
- Кэш данных шарда хранит результаты часто используемых запросов, где size=0, в частности результаты агрегирования. Этот кэш особенно актуален для случаев использования логгирования, когда данные не обновляются по старым индексам, а регулярные агрегации могут храниться в кэше для повторного использования.
- Кэш полевых данных используется для сортировки и агрегирования. Чтобы эти операции выполнялись быстро, Elasticsearch загружает эти значения в память.
Примеры
Обычно Elasticsearch управляет кэшем «за сценой», не требуя каких-либо специальных настроек. Однако можно отслеживать и ограничивать объем памяти, используемой на каждом узле для определенного типа кэша, прописав следующее в файле elasticsearch.yml :
1 2 | indices.queries.cache.size: 10% indices.fielddata.cache.size: 30% |
Обратите внимание, что приведенные выше значения являются значениями по умолчанию, и нет необходимости устанавливать их специально. Значения по умолчанию подходят для большинства случаев использования, и их редко следует изменять.
Вы можете отслеживать использование кэша на каждом узле следующим образом:
1 2 3 | GET /_nodes/stats/indices/fielddata GET /_nodes/stats/indices/query_cache GET /_nodes/stats/indices/request_cache |
Примечания и полезные советы
Создавайте запросы с фильтрами многократного использования. Существуют определенные части запроса, которые являются хорошими кандидатами на повторное использование в большом количестве запросов, и вы должны разрабатывать свои запросы с учетом этого. Все, что не нуждается в оценке, должно быть помещено в раздел фильтра bool-запроса. Например, временные диапазоны, языковые селекторы или условия, исключающие неактивные документы, скорее всего, будут исключены в большом количестве запросов, и их следует включать в фильтрующие части запроса, чтобы их можно было кэшировать и использовать повторно.
В частности, будьте осторожны с временными фильтрами. «now-15m» нельзя использовать повторно, потому что «now» будет постоянно меняться по мере того, как будет меняться временное окно. С другой стороны, «now-15/m» округляется до ближайшей минуты и может быть повторно использован (через кэш) в течение 60 секунд, после чего переходит на следующую минуту.
Например, когда пользователь вводит поисковый запрос «brexit», мы можем захотеть отфильтровать его по языку и периоду времени, чтобы вернуть релевантные статьи. В приведенном ниже запросе в части «must» оставлен только термин «brexit», потому что это единственная часть, которая должна влиять на оценку релевантности. Фильтр по времени и фильтр по языку можно использовать снова и снова для новых запросов по разным поисковым запросам.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | POST results/_search { "query": { "bool": { "must": [ { "match": { "message": { "query": "brexit" } } } ], "filter": [ { "range": { "@timestamp": { "gte": "now-10d/d" } } }, { "term": { "lang.keyword": { "value": "en", "boost": 1 } } } ] } } } |
Ограничьте использование полевых данных. Будьте осторожны с использованием fielddata=true в отображении, если количество терминов приведет к высокой кардинальности. Если вы должны использовать fielddata=true, вы также можете уменьшить потребность в кэше полевых данных, ограничив требования к полевым данным для данного индекса с помощью фильтра частоты полевых данных.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | POST results/_search { "query": { "bool": { "must": [ { "match": { "message": { "query": "brexit" } } } ], "filter": [ { "range": { "@timestamp": { "gte": "now-10d/d" } } }, { "term": { "lang.keyword": { "value": "en", "boost": 1 } } } ] } } } |