Маршрутизация фрагментов поиска
Для защиты от сбоев оборудования и увеличения объёма поисковых возможностей Elasticsearch может хранить копии данных индекса на нескольких фрагментах на нескольких узлах. При выполнении запроса на поиск Elasticsearch выбирает узел, содержащий копию данных индекса, и пересылает запрос на поиск фрагментам этого узла. Этот процесс известен как маршрутизация фрагментов поиска или маршрутизация.
Адаптивная выборка реплик
По умолчанию Elasticsearch использует адаптивную выборку реплик для маршрутизации поисковых запросов. Этот метод выбирает подходящий узел, используя осознанность распределения фрагментов и следующие критерии:
- Время ответа предыдущих запросов между узлом координации и подходящим узлом
- Время, затраченное подходящим узлом на выполнение предыдущих поисков
- Размер очереди
searchпула потоков подходящего узла
Адаптивная выборка реплик разработана для уменьшения задержки поиска. Однако вы можете отключить адаптивную выборку реплик, установив cluster.routing.use_adaptive_replica_selection на false, используя API настроек кластера. Если она отключена, Elasticsearch маршрутизирует поисковые запросы методом круговой очереди, что может привести к более медленным поискам.
Установить предпочтение
По умолчанию адаптивная выборка реплик выбирает из всех подходящих узлов и фрагментов. Однако вам может потребоваться получить данные только с локального узла или направить поиск на конкретный узел на основе его оборудования. Или вам может потребоваться отправлять повторяющиеся запросы на тот же фрагмент для использования кэширования.
Для ограничения набора узлов и фрагментов, подходящих для поискового запроса, используйте параметр запроса API поиска preference.
Например, следующий запрос ищет my-index-000001 с preference значением _local. Это ограничивает поиск фрагментами на локальном узле. Если локальный узел не содержит копий фрагментов данных индекса, запрос использует адаптивную выборку реплик на другом подходящем узле в качестве резервного варианта.
resp = client.search(
index="my-index-000001",
preference="_local",
query={
"match": {
"user.id": "kimchy"
}
},
)
print(resp) response = client.search(
index: 'my-index-000001',
preference: '_local',
body: {
query: {
match: {
'user.id' => 'kimchy'
}
}
}
)
puts response const response = await client.search({
index: "my-index-000001",
preference: "_local",
query: {
match: {
"user.id": "kimchy",
},
},
});
console.log(response); GET /my-index-000001/_search?preference=_local
{
"query": {
"match": {
"user.id": "kimchy"
}
}
} Вы также можете использовать параметр preference для маршрутизации поисковых запросов на определенные фрагменты на основе предоставленной строки. Если состояние кластера и выбранные фрагменты не изменятся, запросы, использующие ту же строку preference, маршрутизируются на те же фрагменты в том же порядке.
Рекомендуется использовать уникальную строку preference, такую как имя пользователя или идентификатор сеанса веб-приложения. Эта строка не может начинаться с _.
Вы можете использовать этот параметр для обработки кэшированных результатов для часто используемых и ресурсоёмких запросов. Если данные фрагмента не изменяются, повторяющиеся запросы с той же строкой preference извлекают результаты из того же кэша запросов фрагмента. Для случаев использования временных рядов, таких как логирование, данные в более старых индексах редко обновляются и могут быть обработаны непосредственно из этого кэша.
Следующий запрос ищет my-index-000001 со строкой preference значением my-custom-shard-string.
resp = client.search(
index="my-index-000001",
preference="my-custom-shard-string",
query={
"match": {
"user.id": "kimchy"
}
},
)
print(resp) response = client.search(
index: 'my-index-000001',
preference: 'my-custom-shard-string',
body: {
query: {
match: {
'user.id' => 'kimchy'
}
}
}
)
puts response const response = await client.search({
index: "my-index-000001",
preference: "my-custom-shard-string",
query: {
match: {
"user.id": "kimchy",
},
},
});
console.log(response); GET /my-index-000001/_search?preference=my-custom-shard-string
{
"query": {
"match": {
"user.id": "kimchy"
}
}
} Если состояние кластера или выбранные фрагменты изменяются, та же строка preference может не маршрутизировать запросы на те же фрагменты в том же порядке. Это может произойти по ряду причин, включая перемещение фрагментов и сбои фрагментов. Узел также может отклонить запрос на поиск, который Elasticsearch перенаправит на другой узел.
Использование значения маршрутизации
При индексировании документа вы можете указать необязательное значение маршрутизации, которое маршрутизирует документ на определенный фрагмент.
Например, следующий запрос индексирования маршрутизирует документ, используя my-routing-value.
resp = client.index(
index="my-index-000001",
routing="my-routing-value",
document={
"@timestamp": "2099-11-15T13:12:00",
"message": "GET /search HTTP/1.1 200 1070000",
"user": {
"id": "kimchy"
}
},
)
print(resp) response = client.index(
index: 'my-index-000001',
routing: 'my-routing-value',
body: {
"@timestamp": '2099-11-15T13:12:00',
message: 'GET /search HTTP/1.1 200 1070000',
user: {
id: 'kimchy'
}
}
)
puts response const response = await client.index({
index: "my-index-000001",
routing: "my-routing-value",
document: {
"@timestamp": "2099-11-15T13:12:00",
message: "GET /search HTTP/1.1 200 1070000",
user: {
id: "kimchy",
},
},
});
console.log(response); POST /my-index-000001/_doc?routing=my-routing-value
{
"@timestamp": "2099-11-15T13:12:00",
"message": "GET /search HTTP/1.1 200 1070000",
"user": {
"id": "kimchy"
}
} Вы можете использовать то же значение маршрутизации в параметре запроса API поиска routing. Это гарантирует, что поиск выполняется на том же фрагменте, что использовался для индексирования документа.
resp = client.search(
index="my-index-000001",
routing="my-routing-value",
query={
"match": {
"user.id": "kimchy"
}
},
)
print(resp) response = client.search(
index: 'my-index-000001',
routing: 'my-routing-value',
body: {
query: {
match: {
'user.id' => 'kimchy'
}
}
}
)
puts response const response = await client.search({
index: "my-index-000001",
routing: "my-routing-value",
query: {
match: {
"user.id": "kimchy",
},
},
});
console.log(response); GET /my-index-000001/_search?routing=my-routing-value
{
"query": {
"match": {
"user.id": "kimchy"
}
}
} Вы также можете указать несколько значений маршрутизации, разделенных запятыми:
resp = client.search(
index="my-index-000001",
routing="my-routing-value,my-routing-value-2",
query={
"match": {
"user.id": "kimchy"
}
},
)
print(resp) response = client.search(
index: 'my-index-000001',
routing: 'my-routing-value,my-routing-value-2',
body: {
query: {
match: {
'user.id' => 'kimchy'
}
}
}
)
puts response const response = await client.search({
index: "my-index-000001",
routing: "my-routing-value,my-routing-value-2",
query: {
match: {
"user.id": "kimchy",
},
},
});
console.log(response); GET /my-index-000001/_search?routing=my-routing-value,my-routing-value-2
{
"query": {
"match": {
"user.id": "kimchy"
}
}
} Конкурентность и параллельность поиска
По умолчанию Elasticsearch не отклоняет запросы на поиск на основе количества фрагментов, на которые этот запрос воздействует. Однако обращение к большому количеству фрагментов может значительно увеличить использование ЦП и памяти.
Советы по предотвращению индексов с большим количеством фрагментов см. в разделе Настройка размера фрагментов.
Вы можете использовать параметр max_concurrent_shard_requests для управления максимальным количеством одновременных фрагментов, на которые может воздействовать поисковый запрос на узел. Это предотвращает перегрузку кластера одним запросом. Параметр по умолчанию устанавливает максимум 5.
resp = client.search(
index="my-index-000001",
max_concurrent_shard_requests="3",
query={
"match": {
"user.id": "kimchy"
}
},
)
print(resp) response = client.search(
index: 'my-index-000001',
max_concurrent_shard_requests: 3,
body: {
query: {
match: {
'user.id' => 'kimchy'
}
}
}
)
puts response const response = await client.search({
index: "my-index-000001",
max_concurrent_shard_requests: 3,
query: {
match: {
"user.id": "kimchy",
},
},
});
console.log(response); GET /my-index-000001/_search?max_concurrent_shard_requests=3
{
"query": {
"match": {
"user.id": "kimchy"
}
}
} Вы также можете использовать настройку кластера action.search.shard_count.limit для установки ограничения фрагментов поиска и отклонения запросов, которые воздействуют на слишком большое количество фрагментов. Вы можете настроить action.search.shard_count.limit с помощью API настроек кластера.
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-shard-routing.html