Устранение неполадок со здоровьем кластера Elasticsearch: пошаговое руководство
Столкнулись с желтым или красным кластером Elasticsearch? Диагностика неназначенных шардов, проблем с диском, потери узлов и безопасные варианты восстановления.
Устранение неполадок со здоровьем кластера Elasticsearch: пошаговое руководство
Желтый или красный кластер Elasticsearch — это не загадочное состояние. Обычно это означает, что Elasticsearch не может разместить один или несколько шардов там, где хочет. Задача — найти, какой шард застрял, почему выделение заблокировано, и правильное ли решение — подождать, освободить ресурсы, вернуть узел, восстановить из снимка или намеренно допустить потерю данных.
Я рассматриваю состояние здоровья кластера как сигнал для сортировки, а не как сам диагноз. Зеленый означает, что каждый первичный и реплика-шард назначены. Желтый означает, что все первичные шарды назначены, поэтому поиск и запись обычно могут продолжаться, но отсутствует хотя бы одна реплика. Красный означает, что хотя бы один первичный шард не назначен, поэтому часть хотя бы одного индекса недоступна. Красный — это то, что может немедленно нарушить чтение или запись приложения.
Начните с получения простого представления:
GET /_cluster/health?pretty
GET /_cat/health?v
Посмотрите на status, number_of_nodes, active_primary_shards, unassigned_shards, initializing_shards и relocating_shards. Если вы видите инициализирующиеся или перемещающиеся шарды после перезапуска узла, кластер, возможно, уже восстанавливается. Не начинайте изменять настройки выделения, пока не узнаете, просто ли Elasticsearch выполняет работу.
Затем перечислите неназначенные шарды:
GET /_cat/shards?v&h=index,shard,prirep,state,node,unassigned.reason&s=state,index,shard
Столбец prirep важен. Шард p — первичный. Красный кластер всегда имеет хотя бы один неназначенный первичный шард. Шард r — реплика. Желтый кластер обычно имеет только неназначенные реплики.
Наиболее полезный API в этой ситуации — allocation explain:
GET /_cluster/allocation/explain?pretty
Для конкретного шарда уточните:
GET /_cluster/allocation/explain?pretty
{
"index": "logs-2026.05.24",
"shard": 0,
"primary": false
}
Прочитайте ответ can_allocate и решения на уровне узлов. Elasticsearch обычно точно сообщает, какое правило заблокировало выделение: дисковые маркеры, фильтрация выделения, правила одного шарда, задержка выделения после ухода узла, отсутствие данных первичного шарда, несовместимые версии или несоответствие ролей узлов.
Когда кластер желтый
Желтый цвет распространен в небольших кластерах. Классический случай — одоузловой кластер для разработки с number_of_replicas: 1. Elasticsearch не может разместить реплику на том же узле, что и ее первичный шард, поэтому реплика остается неназначенной навсегда. Это не чрезвычайная ситуация в среде ноутбука. Это несоответствие конфигурации.
Проверьте количество реплик:
GET /my-index/_settings?filter_path=*.settings.index.number_of_replicas
Для одоузлового нерабочего кластера установите реплики в ноль:
PUT /my-index/_settings
{
"index": {
"number_of_replicas": 0
}
}
Для рабочей среды не скрывайте проблему, уменьшая количество реплик, если только вы намеренно не принимаете меньшую избыточность. Если индекс должен иметь одну реплику, вам нужно как минимум два подходящих узла данных. Если у него две реплики, вам нужно как минимум три подходящих узла данных. Уровневая структура может сделать это менее очевидным: реплика теплого индекса не может быть выделена на узел только горячих данных, если правила выделения требуют теплых узлов.
Давление на диск — следующая распространенная причина желтого цвета. Проверьте использование диска узлами:
GET /_cat/allocation?v
GET /_cat/nodes?v&h=name,roles,disk.used_percent,disk.avail,heap.percent,cpu,load_1m
Elasticsearch использует дисковые маркеры, чтобы избежать заполнения узлов. Значения по умолчанию различаются в зависимости от версии и конфигурации, поэтому проверьте фактические настройки вашего кластера:
GET /_cluster/settings?include_defaults=true&flat_settings=true&filter_path=**cluster.routing.allocation.disk.watermark**
Если узел превышает высокий маркер, Elasticsearch будет избегать выделения дополнительных шардов на нем. Если он достигает маркера flood-stage, Elasticsearch может перевести затронутые индексы в состояние блокировки записи, чтобы защитить узел. Долговременное исправление — удалить старые данные, переместить данные на большее количество узлов, увеличить диск, уменьшить количество чрезмерно больших шардов или настроить ILM-политику хранения. Временное повышение маркеров может выиграть время, но это не должно быть вашим первым шагом.
Практическая последовательность очистки выглядит так:
GET /_cat/indices?v&s=store.size:desc
GET /_cat/shards?v&s=store:desc
Найдите большие старые индексы, проверьте ожидания по хранению с ответственной командой, сделайте снимок при необходимости, затем удалите только те данные, которые вам разрешено удалять:
DELETE /old-logs-2025.12.*
После освобождения места выделение может возобновиться автоматически. Если этого не произошло, повторно запустите allocation explain. Старая причина может все еще быть в вашей голове, но теперь кластер может быть заблокирован другим правилом.
Фильтрация выделения — еще одна частая причина желтого цвета, особенно после миграции оборудования. Кто-то мог установить для индекса требование атрибута узла, который больше не существует:
GET /my-index/_settings?flat_settings=true&filter_path=*.settings.index.routing.allocation*
GET /_cluster/settings?flat_settings=true&filter_path=**routing.allocation**
Если правило неверно, удалите или обновите его:
PUT /my-index/_settings
{
"index.routing.allocation.require.box_type": null,
"index.routing.allocation.include._name": null,
"index.routing.allocation.exclude._name": null
}
Используйте точные ключи, которые показывают ваши настройки. Не вставляйте широкий сброс в рабочую среду, не прочитав его; правила выделения иногда существуют по уважительной причине, например, для хранения определенных данных на уровне, контролируемом требованиями соответствия.
Когда кластер красный
Красный цвет требует более медленных действий и лучших заметок. Первый вопрос — есть ли у отсутствующего первичного шарда восстанавливаемая копия где-либо.
Перечислите неназначенные первичные шарды:
GET /_cat/shards?v&h=index,shard,prirep,state,unassigned.reason | grep ' p UNASSIGNED'
Затем проверьте, какие узлы присутствуют:
GET /_cat/nodes?v&h=name,ip,roles,master,uptime,heap.percent,disk.avail
Если узел отсутствует, ваш лучший путь восстановления — часто вернуть этот узел. Проверьте службу, точку монтирования диска, сеть хоста, сертификаты и журналы на отсутствующем узле. Узел, потерявший доступ к своему пути данных, может запуститься как другой пустой узел, что не поможет восстановить первичный шард.
На узле Elasticsearch журналы обычно показывают реальную ошибку быстрее, чем API. Ищите сообщения об ошибках блокировки шардов, поврежденных файлах индексов, обнаружении мастера, ошибках рукопожатия TLS, файловых системах только для чтения или изменениях ролей узлов. Распространенный сбой в реальном мире — перезапуск узла после того, как диск был перемонтирован по другому пути. Elasticsearch запускается, но путь данных пуст, поэтому кластеру по-прежнему не хватает необходимой копии шарда.
Запустите allocation explain для первичного шарда:
GET /_cluster/allocation/explain?pretty
{
"index": "orders-2026.05.24",
"shard": 2,
"primary": true
}
Если объяснение говорит, что действительная копия шарда не найдена, остановитесь и проверьте снимки, прежде чем делать что-либо разрушительное:
GET /_snapshot/_all
GET /_snapshot/my-repository/_all?verbose=false
Восстановление из снимка обычно безопаснее, чем выделение пустого первичного шарда. Пустой первичный шард создает новый пустой шард для этого идентификатора шарда. Это не операция восстановления. Это говорит Elasticsearch: "Я принимаю, что старые данные для этого шарда потеряны".
Команда последней надежды выглядит так:
POST /_cluster/reroute
{
"commands": [
{
"allocate_empty_primary": {
"index": "orders-2026.05.24",
"shard": 2,
"node": "es-data-03",
"accept_data_loss": true
}
}
]
}
Используйте ее только после того, как вы подтвердили, что нет доступной копии узла и нет снимка, который можно восстановить. В случае инцидента запишите, кто одобрил этот выбор и какие индекс и шард были затронуты. Будущая отладка будет намного проще, если решение о потере данных будет явным.
Случаи, которые выглядят как проблемы с выделением, но на самом деле являются проблемами кластера
Иногда шарды не назначаются, потому что кластер не может поддерживать стабильное членство. Если узлы, имеющие право быть мастером, не могут общаться друг с другом, выбранный мастер может меняться многократно, и выделение будет циклически меняться или приостанавливаться. Проверьте стабильность мастера:
GET /_cat/master?v
GET /_cat/nodes?v&h=name,roles,master,ip
Если мастер часто меняется, проверьте надежность сети, DNS, сертификаты узлов и настройки обнаружения. Для современных кластеров Elasticsearch cluster.initial_master_nodes предназначен для начальной загрузки кластера, а не для того, чтобы оставлять его как постоянную опору для обнаружения. discovery.seed_hosts должен указывать на соответствующие seed-хосты, и все узлы должны использовать одно и то же имя кластера и совместимые настройки безопасности.
Высокое давление JVM также может вызывать симптомы выделения. Узел данных, застрявший в длительных паузах сборки мусора, может покинуть и повторно присоединиться к кластеру с точки зрения мастера. Это может создать неназначенные шарды, даже если машина никогда полностью не выходила из строя.
Проверьте кучу и журналы сборки мусора:
GET /_cat/nodes?v&h=name,heap.percent,ram.percent,cpu,load_1m,node.role
GET /_nodes/stats/jvm?filter_path=nodes.*.jvm.mem,nodes.*.jvm.gc
Если куча постоянно высока, не увеличивайте ее слепо. Elasticsearch обычно работает лучше всего, когда куча оставляет достаточно памяти для кэша файловой системы. Ищите чрезмерно большие агрегации, интенсивное использование fielddata, слишком много шардов, агрессивную индексацию или запросы, требующие лучших маппингов.
Количество шардов может быть тихой причиной многих проблем со здоровьем. Кластер с множеством крошечных шардов тратит слишком много усилий на отслеживание метаданных и перемещение шардов. Используйте:
GET /_cat/indices?v&h=index,pri,rep,docs.count,store.size,pri.store.size&s=pri:desc
GET /_cluster/stats?filter_path=indices.shards,indices.count,nodes.count
Если каждый ежедневный индекс журнала имеет много первичных шардов, но мало данных, исправьте шаблон индекса для будущих индексов. Затем рассмотрите планы shrink, rollover или reindex для существующих данных.
Практический порядок сортировки
Когда кто-то говорит "Elasticsearch красный", я использую этот порядок:
- Подтвердите состояние здоровья с помощью
_cluster/health. - Перечислите неназначенные шарды с помощью
_cat/shards. - Отделите отказы первичных шардов от отказов реплик.
- Запустите
_cluster/allocation/explainдля одного репрезентативного шарда. - Проверьте, присутствуют ли все ожидаемые узлы.
- Проверьте дисковые маркеры и правила выделения.
- Для красных первичных шардов попробуйте восстановить отсутствующий узел или восстановить из снимка, прежде чем рассматривать выделение пустого первичного шарда.
- После того как кластер станет зеленым, найдите причину, которая сделала его нездоровым в первую очередь.
Этот последний шаг важен. Кластер может стать зеленым после того, как вы добавите диск, перезапустите узел или уменьшите количество реплик, но тот же инцидент вернется, если ILM-политика хранения неверна, количество шардов слишком велико, узлы недостаточно мощны или процесс развертывания продолжает изменять атрибуты узлов.
Устранение неполадок со здоровьем кластера заключается не в запоминании одной волшебной команды, а в отказе от догадок. Elasticsearch раскрывает решение о выделении. Прочитайте его, проверьте на соответствие настройкам узлов и индексов и выберите наименьшее исправление, которое соответствует фактическому блокировщику.
После того как кластер снова стал зеленым
Не закрывайте инцидент только потому, что цвет изменился. Зеленый означает только то, что шарды назначены сейчас. Это не доказывает, что кластер достаточно здоров для следующего всплеска трафика, цикла роста диска или перезапуска узла. Мне нравится делать краткую заметку после действия, пока детали еще свежи: какие индексы были затронуты, какие узлы были вовлечены, какое правило выделения заблокировало восстановление и какая команда или изменение инфраструктуры это исправило.
Проверьте, не создало ли исправление новый риск. Если вы уменьшили количество реплик, чтобы превратить желтый в зеленый, запишите, что индекс теперь имеет меньшую избыточность. Если вы повысили дисковые маркеры, добавьте напоминание, чтобы снизить их после добавления емкости. Если вы восстановили снимок, проверьте, что восстановленный индекс имеет ожидаемые псевдонимы и настройки записи, прежде чем приложения возобновят нормальную запись.
Несколько быстрых проверок помогают выявить незавершенную работу:
GET /_cat/recovery?v&active_only=true
GET /_cat/pending_tasks?v
GET /_cat/aliases?v
GET /_cluster/health?wait_for_status=green&timeout=30s
pending_tasks не должны расти бесконечно. Восстановление должно в конечном итоге завершиться. Псевдонимы важны, потому что восстановление индекса под другим именем может привести к тому, что приложение будет писать в старую сломанную цель или читать только часть предполагаемых данных.
Также проверьте блокировки записи после инцидентов с диском:
GET /*/_settings?filter_path=*.settings.index.blocks*
Если Elasticsearch установил блок flood-stage, удалите его только после устранения проблемы с диском:
PUT /my-index/_settings
{
"index.blocks.read_only_allow_delete": null
}
Наиболее полезная профилактическая работа обычно скучна: рабочие снимки, протестированные восстановления, реалистичная ILM-политика хранения, достаточный запас диска и количество шардов, соответствующее размеру кластера. Кластер с надежными снимками и разумным размером шардов гораздо легче восстановить, чем кластер с умными аварийными командами и отсутствием пути восстановления.
Чего не следует делать во время инцидентов со здоровьем
Не перезапускайте все узлы одновременно. Это заманчиво, когда кластер выглядит нездоровым, но безопаснее поэтапный, наблюдаемый подход. Перезапуск здоровых узлов может удалить копии шардов, которые Elasticsearch нужны для восстановления. Если вам нужно перезапустить, делайте это по одному узлу за раз и ждите стабилизации кластера между шагами.
Не отключайте выделение и не забывайте об этом. Временные изменения выделения распространены во время обслуживания, но забытая настройка может оставить реплики неназначенными задолго до окончания окна обслуживания. Всегда проверяйте как постоянные, так и временные настройки:
GET /_cluster/settings?flat_settings=true&include_defaults=false
Не удаляйте индексы, основываясь только на размере. Большие индексы могут быть критически важными для бизнеса. Маленькие индексы могут быть безопасны для удаления. Привяжите очистку к политике хранения, снимкам и владельцам приложений. В реальном сбое самая быстрая безопасная очистка обычно заключается в удалении известных просроченных индексов журналов или метрик, а не в догадках из отсортированного списка размеров.
Не предполагайте, что Kibana и Elasticsearch используют один и тот же язык для описания проблемы. Kibana может показывать широкий красный статус, в то время как API Elasticsearch показывают точный неназначенный шард. Используйте пользовательский интерфейс для видимости, но используйте API для принятия решений.