Отсрочка распределения при выходе узла из кластера
Когда узел по каким-либо причинам, намеренно или непреднамеренно, покидает кластер, мастер реагирует следующим образом:
- Превращает фрагмент-реплику в фрагмент-первичный для замены любого первичного фрагмента, который находился на узле.
- Распределяет фрагменты-реплики для замены отсутствующих реплик (при условии достаточного количества узлов).
- Перераспределяет фрагменты равномерно по оставшимся узлам.
Эти действия предназначены для защиты кластера от потери данных, гарантируя, что каждый фрагмент будет полностью дублирован как можно быстрее.
Несмотря на то, что мы ограничиваем одновременные восстановления как на уровне узла, так и на уровне кластера, эта «перетасовка фрагментов» всё ещё может накладывать значительную нагрузку на кластер, что может быть не нужно, если отсутствующий узел, вероятно, скоро вернётся. Представьте себе такую ситуацию:
- Узел 5 теряет сетевое соединение.
- Мастер превращает фрагмент-реплику в фрагмент-первичный для каждого первичного фрагмента, который находился на узле 5.
- Мастер распределяет новые реплики на другие узлы в кластере.
- Каждая новая реплика создаёт полную копию первичного фрагмента через сеть.
- Больше фрагментов перемещается на разные узлы для перебалансировки кластера.
- Узел 5 возвращается через несколько минут.
- Мастер перебалансирует кластер, распределяя фрагменты на узел 5.
Если бы мастер просто подождал несколько минут, отсутствующие фрагменты можно было бы перераспределить на узел 5 с минимальным объёмом сетевого трафика. Этот процесс будет ещё быстрее для простаивающих фрагментов (фрагментов, не получающих запросы индексирования), которые автоматически очищаются.
Распределение фрагментов-реплик, которые становятся неназначенными из-за выхода узла, можно отсрочить с помощью динамической настройки index.unassigned.node_left.delayed_timeout, которая по умолчанию равна 1m.
Данную настройку можно обновить в активном индексе (или для всех индексов):
resp = client.indices.put_settings(
index="_all",
settings={
"settings": {
"index.unassigned.node_left.delayed_timeout": "5m"
}
},
)
print(resp) response = client.indices.put_settings(
index: '_all',
body: {
settings: {
'index.unassigned.node_left.delayed_timeout' => '5m'
}
}
)
puts response const response = await client.indices.putSettings({
index: "_all",
settings: {
settings: {
"index.unassigned.node_left.delayed_timeout": "5m",
},
},
});
console.log(response); PUT _all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "5m"
}
} При включённой отсрочке распределения описанный сценарий изменяется следующим образом:
- Узел 5 теряет сетевое соединение.
- Мастер превращает фрагмент-реплику в фрагмент-первичный для каждого первичного фрагмента, который находился на узле 5.
- Мастер записывает сообщение о том, что распределение неназначенных фрагментов отложено, и на какой срок.
- Кластер остаётся в жёлтом состоянии, так как есть неназначенные фрагменты-реплики.
- Узел 5 возвращается через несколько минут, прежде чем истечёт срок действия
timeout. - Отсутствующие реплики перераспределяются на узел 5 (и фрагменты с очисткой синхронизируются практически мгновенно).
Эта настройка не повлияет на превращение реплик в первичные, а также не повлияет на распределение реплик, которые ранее не были назначены. В частности, отсрочка распределения не вступает в силу после полной перезагрузки кластера. Кроме того, в случае переключения мастера отложенное время игнорируется (то есть сбрасывается до первоначального значения).
Отмена перемещения фрагментов
Если время отсрочки распределения истекает, мастер назначает отсутствующие фрагменты другому узлу, который начнёт восстановление. Если отсутствующий узел присоединяется к кластеру и его фрагменты по-прежнему имеют тот же идентификатор синхронизации, что и первичный фрагмент, перемещение фрагментов будет отменено, и синхронизированный фрагмент будет использован для восстановления.
По этой причине значение по умолчанию timeout установлено всего на одну минуту: даже если началось перемещение фрагментов, отмена восстановления в пользу синхронизированного фрагмента стоит недорого.
Мониторинг отложенных неназначенных фрагментов
Количество фрагментов, распределение которых отложено по настройке таймаута, можно просмотреть с помощью API состояния кластера:
resp = client.cluster.health() print(resp)
response = client.cluster.health puts response
const response = await client.cluster.health(); console.log(response);
GET _cluster/health
| Этот запрос вернёт значение |
Постоянное удаление узла
Если узел не вернётся и вы хотите, чтобы Elasticsearch немедленно распределял отсутствующие фрагменты, просто обновите таймаут на ноль:
resp = client.indices.put_settings(
index="_all",
settings={
"settings": {
"index.unassigned.node_left.delayed_timeout": "0"
}
},
)
print(resp) response = client.indices.put_settings(
index: '_all',
body: {
settings: {
'index.unassigned.node_left.delayed_timeout' => '0'
}
}
)
puts response const response = await client.indices.putSettings({
index: "_all",
settings: {
settings: {
"index.unassigned.node_left.delayed_timeout": "0",
},
},
});
console.log(response); PUT _all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "0"
}
} Вы можете сбросить таймаут, как только восстановление отсутствующих фрагментов начнётся.
© 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/delayed-allocation.html