Для повышения эффективности работы OpenSearch использует три типа кэшей.
- Кэш запросов узлов
- Кэш данных шардов
- Кэш данных полей
Принцип их работы
Кэш запросов узла хранит результаты запросов, используемых в контексте фильтра. Результаты вытесняются по принципу наименьшего количества последних использованных запросов.
Кэш данных шарда хранит результаты часто используемых запросов, где size=0, в частности, результаты агрегирования. Этот кэш особенно актуален для случаев использования логгирования, когда данные не обновляются по старым индексам, а регулярные агрегации могут храниться в кэше для повторного использования.
Кэш полевых данных используется для сортировки и агрегирования. Чтобы эти операции выполнялись быстро, OpenSearch загружает эти значения в память.
Примеры
Обычно OpenSearch управляет кэшем "за сценой", не требуя каких-либо специальных настроек. Однако можно контролировать и ограничивать объем памяти, используемой на каждом узле для данного типа кэша, прописав в OpenSearch.yml следующее :
1 2 | indices.queries.cache.size: 10% indices.fielddata.cache.size: 30% |
Обратите внимание, что приведенные выше значения фактически являются значениями по умолчанию, и нет необходимости задавать их специально. Значения по умолчанию подходят для большинства случаев использования, и их не следует изменять.
Отследить использование кэша на каждом узле можно следующим образом:
1 2 3 4 5 | 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 } } } ] } } } |