Проблемы распределения шардов в Elasticsearch: причины и решения
Диагностика проблем распределения шардов Elasticsearch с помощью allocation explain, проверки диска, фильтров узлов и безопасных шагов восстановления.
Проблемы распределения шардов Elasticsearch: причины и решения
Проблемы распределения шардов Elasticsearch обычно проявляются как желтый или красный статус кластера. Желтый означает, что ваши основные шарды назначены, но хотя бы одна реплика — нет. Красный означает, что как минимум один основной шард не назначен, поэтому некоторые данные могут быть недоступны до их восстановления.
Это руководство покажет вам, как найти блокировщик распределения, прочитать вывод API Allocation Explain и выбрать наименее рискованное исправление. Цель — восстановить распределение без усугубления потери данных.
Понимание состояний шардов и здоровья кластера
Шарды — это единица, которую Elasticsearch размещает на узлах данных. Они могут находиться в нескольких состояниях:
- STARTED: Шард активен и обслуживает запросы.
- RELOCATING: Шард перемещается с одного узла на другой.
- INITIALIZING: Шард создается или восстанавливается.
- UNASSIGNED: Шард существует в метаданных кластера, но не распределен на узел.
Здоровье кластера следует за этими состояниями шардов:
- Green: Все основные шарды и реплики распределены.
- Yellow: Все основные шарды распределены, но одна или несколько реплик не назначены.
- Red: Один или несколько основных шардов не назначены. Поиск может возвращать частичные результаты или завершаться ошибкой для затронутых индексов, а запись в эти индексы может быть невозможна.
Распространенные причины сбоев распределения шардов
Elasticsearch использует решающие факторы распределения перед размещением шарда. Одно решение NO может оставить шард неназначенным.
Дисковые водяные знаки
Давление на диск — одна из самых распространенных причин. Elasticsearch использует дисковые водяные знаки, чтобы избежать заполнения узла. Как только узел пересекает низкий или высокий водяной знак, решения о распределении становятся более ограничительными. На стадии flood-stage Elasticsearch может добавить блокировку только для чтения к затронутым индексам, чтобы защитить узел от нехватки дискового пространства.
| Настройка | Общее значение по умолчанию | Эффект |
|---|---|---|
cluster.routing.allocation.disk.watermark.low |
85% | Избегает распределения дополнительных шардов на узлы выше этого порога. |
cluster.routing.allocation.disk.watermark.high |
90% | Пытается переместить шарды и избегает размещения шардов на узле. |
cluster.routing.allocation.disk.watermark.flood_stage |
95% | Может блокировать запись в затронутые индексы. |
Подтвердите фактические настройки вашего кластера перед любыми изменениями:
GET /_cluster/settings?include_defaults=true&filter_path=**.disk.watermark*
Затем проверьте использование диска узлами:
GET /_cat/allocation?v&h=node,disk.used_percent,disk.avail,disk.total,shards
Освободите место, добавьте диск, добавьте узлы данных, удалите старые индексы или уменьшите давление реплик. Если была установлена блокировка flood-stage, удалите ее только после устранения проблемы с диском:
PUT /my_index/_settings
{
"index.blocks.read_only_allow_delete": null
}
Роли узлов и фильтры распределения
Шарды индекса распределяются только на узлы с ролью данных и соответствующими фильтрами распределения. Если вы используете атрибуты узлов для горячих/холодных уровней, стоек, зон или типов хранилищ, опечатка может заблокировать шарды.
Например, индекс с index.routing.allocation.require.box_type: high_io будет распределяться только на узлы, настроенные с node.attr.box_type: high_io.
Проверьте фильтры индексов и атрибуты узлов:
GET /my_index/_settings?filter_path=*.settings.index.routing.allocation
GET /_cat/nodeattrs?v
GET /_cat/nodes?v&h=name,roles,disk.used_percent
Исправьте настройку индекса или добавьте подходящий узел данных. Не удаляйте осведомленность о распределении в многозонных кластерах без необходимости; это может разместить все копии шарда в одной зоне отказа.
Отсутствующие основные шарды
Если основной шард не назначен, узел, содержащий активный основной шард, может быть недоступен, индекс мог быть только что восстановлен, или правила распределения могут блокировать все подходящие узлы. Не предполагайте потерю данных, пока API Allocation Explain не скажет вам, почему Elasticsearch не может распределить шард.
Распространенные сценарии включают:
- Узел, содержащий единственную хорошую копию основного шарда, вышел из строя.
- Фильтры распределения исключают все узлы данных, которые могли бы разместить основной шард.
- Восстановление из снимка или создание индекса ожидает подходящие узлы.
- Существует устаревшая копия шарда, но Elasticsearch не продвигает ее без явного согласия на потерю данных.
Сначала попробуйте восстановить отсутствующий узел, восстановить снимок или исправить блокировщик распределения. Используйте принудительное распределение основного шарда только тогда, когда вы понимаете, какая копия устарела, или когда вы приняли потерю данных для этого шарда.
Лимиты шардов
Лимиты шардов на узел также могут блокировать распределение. Распространенные настройки включают index.routing.allocation.total_shards_per_node и cluster.routing.allocation.total_shards_per_node.
Проверьте эти лимиты:
GET /_cluster/settings?include_defaults=true&filter_path=**.total_shards_per_node
GET /my_index/_settings?filter_path=*.settings.index.routing.allocation.total_shards_per_node
Добавьте узлы, уменьшите количество реплик, объедините маленькие индексы или осторожно увеличьте соответствующий лимит. Слишком много шардов на узел может увеличить нагрузку на кучу и замедлить операции состояния кластера.
Диагностика с помощью Allocation Explain API
Allocation Explain API — лучший инструмент для ответа на вопрос "почему этот шард не распределяется?"
GET /_cluster/allocation/explain?pretty
{
"index": "my_data",
"shard": 0,
"primary": true
}
Чтобы позволить Elasticsearch выбрать один из текущих неназначенных шардов, вызовите API без тела:
GET /_cluster/allocation/explain?pretty
Сначала прочитайте эти поля:
can_allocate: Ответ высокого уровня.allocate_explanation: Объяснение на простом английском.node_allocation_decisions: Решения по каждому узлу.deciders: Точное правило, которое вернулоNOилиTHROTTLE.
Решение NO является блокировщиком. Решение THROTTLE обычно означает, что Elasticsearch может распределить шард, но ограничивает одновременную работу по восстановлению.
Безопасная последовательность устранения неполадок
Начните с широкого обзора, затем сужайте.
1. Проверьте здоровье кластера и неназначенные шарды
GET /_cluster/health?pretty
GET /_cat/shards?v&h=index,shard,prirep,state,unassigned.reason,node
Посмотрите на unassigned.reason. Значения, такие как NODE_LEFT, INDEX_CREATED, CLUSTER_RECOVERED или ALLOCATION_FAILED, подскажут вам, куда смотреть дальше.
2. Проверьте диск и пригодность узлов
GET /_cat/allocation?v&h=node,disk.used_percent,disk.avail,disk.total
GET /_cat/nodes?v&h=name,roles,heap.percent,ram.percent,cpu,disk.used_percent
Если узлы близки к высокому водяному знаку, сначала исправьте давление на диск, прежде чем менять настройки распределения.
3. Запустите Allocation Explain
Используйте затронутый индекс, номер шарда и флаг основного/реплики. Вывод должен назвать настройку, условие узла или решающий фактор, который блокирует распределение.
4. Избегайте рискованных перемаршрутизаций, пока не узнаете причину
Команды ручной перемаршрутизации предназначены для конкретных случаев восстановления. Они не являются общим исправлением для давления на диск, плохих фильтров или слишком большого количества реплик.
Если устаревшая копия основного шарда является единственным практическим путем восстановления, команда выглядит так:
POST /_cluster/reroute
{
"commands": [
{
"allocate_stale_primary": {
"index": "index_name",
"shard": 0,
"node": "node_name_with_stale_copy",
"accept_data_loss": true
}
}
]
}
accept_data_loss: true требуется не просто так. Используйте его только после того, как проверили снимки, попытались восстановить отсутствующий узел и подтвердили, какой узел содержит устаревшую копию.
5. Обрабатывайте желтое здоровье отдельно
Если не назначены только реплики, кластер все еще может обслуживать основные данные. Сначала исправьте основное ограничение ресурсов. Добавление узла данных, очистка диска или исправление фильтров распределения обычно позволяют Elasticsearch автоматически назначить реплики.
Если вам нужно временно работать без реплик, уменьшите количество реплик для затронутого индекса:
PUT /my_index/_settings
{
"index.number_of_replicas": 0
}
Это может сделать здоровье зеленым, потому что Elasticsearch больше не ожидает копий реплик для этого индекса. Это также снижает доступность, поэтому верните реплики к желаемому значению после добавления емкости или исправления распределения.
Предотвращение проблем с распределением
- Предупреждайте до того, как узлы пересекут высокий дисковый водяной знак.
- Поддерживайте достаточное количество доступных узлов данных для вашего количества реплик и правил осведомленности о распределении.
- Используйте количество шардов, соответствующее вашей куче, объему данных и целям восстановления.
- Проверяйте шаблоны индексов, чтобы новые индексы не наследовали неправильное количество реплик или фильтры распределения.
- Тестируйте замену узлов и шаги восстановления из снимка до инцидента.
Вывод
Ваш самый безопасный путь прост: определите неназначенный шард, запустите Allocation Explain, исправьте решающий фактор, который говорит NO, и избегайте принудительного распределения, если вы не приняли компромисс с потерей данных.