Устранение распространенных сбоев распределения шардов Elasticsearch

Узнайте, как устранять и разрешать распространенные сбои распределения шардов Elasticsearch. Это руководство охватывает выявление неприсвоенных шардов, диагностику таких проблем, как ошибки дискового пространства, недоступность узлов и фильтрация распределения, а также предлагает практические решения и лучшие практики для поддержания работоспособности кластера Elasticsearch.

23 просмотров

Устранение распространенных сбоев при выделении шардов в Elasticsearch

Elasticsearch, мощный распределенный поисковый и аналитический движок, в значительной степени полагается на свою способность распределять данные по нескольким узлам с помощью шардов. Если эти шарды не могут быть выделены, это может привести к недоступности данных, сбоям поиска и ухудшению состояния кластера. Понимание распространенных причин сбоев выделения шардов и знание того, как их диагностировать и устранять, имеет решающее значение для поддержания стабильной и производительной среды Elasticsearch. Эта статья проведет вас по наиболее частым проблемам и предоставит практические шаги для возвращения шардов в назначенное состояние.

Это руководство посвящено практическому устранению неполадок в производственных средах Elasticsearch. Мы рассмотрим идентификацию неназначенных шардов, понимание распространенных причин сбоев, таких как проблемы с дисковым пространством, правилами выделения и проблемами узлов, а также предоставим четкие шаги для эффективного решения этих проблем. Овладев этими методами, вы сможете минимизировать время простоя и обеспечить надежность вашего кластера Elasticsearch.

Идентификация неназначенных шардов

Первый шаг в устранении неполадок — определить, какие шарды не назначены и почему. Elasticsearch предоставляет для этого несколько инструментов:

Использование API состояния кластера (Cluster Health API)

API _cluster/health предоставляет высокоуровневый обзор состояния вашего кластера. Ищите unassigned_shards в ответе. Ненулевое значение указывает на проблему.

GET _cluster/health

Пример фрагмента ответа:

{
  "cluster_name": "my-es-cluster",
  "status": "yellow",
  "timed_out": false,
  "number_of_nodes": 3,
  "number_of_data_nodes": 3,
  "active_primary_shards": 10,
  "active_shards": 20,
  "relocating_shards": 0,
  "initializing_shards": 1,
  "unassigned_shards": 1,
  "delayed_unassigned_shards": 0,
  "number_of_pending_tasks": 0,
  "max_length_search_concurrency": 1000,
  "max_length_search_size": 10000,
  "active_shards_percent_as_number": 95.45454545454545
}

В этом примере "status": "yellow" и "unassigned_shards": 1 указывают на наличие одного неназначенного шарда. Статус red означает, что один или несколько первичных шардов не назначены, что влияет на доступность данных. Статус yellow означает, что реплики шардов не назначены, но первичные шарды выделены, поэтому ваши данные все еще доступны для поиска, но не полностью избыточны.

Использование API объяснения выделения (Allocation Explain API)

Для получения подробной информации о том, почему конкретный шард не назначен, API _cluster/allocation/explain бесценен. Вы можете предоставить детали шарда или позволить ему проанализировать состояние кластера.

Чтобы получить объяснение для любого неназначенного шарда:

GET _cluster/allocation/explain

Чтобы получить объяснение для конкретного шарда (замените index_name и shard_id):

GET _cluster/allocation/explain
{
  "index": "my-index",
  "shard": 0,
  "primary": true
}

Общие причины и решения

Несколько факторов могут привести к тому, что шарды останутся неназначенными. Ниже приведены наиболее распространенные из них и способы их устранения:

1. Недостаточное дисковое пространство

Это, пожалуй, самая частая причина сбоев при выделении шардов. Когда на узле заканчивается дисковое пространство, Elasticsearch предотвращает выделение на него новых шардов, чтобы избежать повреждения данных и обеспечить стабильность. Он также может вытеснять существующие шарды.

  • Симптом: Allocation Explain API часто сообщает сообщения типа "cannot allocate because disk usage [X%] exceeds the low watermark [Y%]" или "cannot allocate because disk usage [X%] exceeds the high watermark [Y%]".
  • Диагностика: Проверьте использование диска на ваших узлах данных. Для быстрого обзора можно использовать API _cat/allocation:
    bash GET _cat/allocation?v
    Ищите узлы с высоким процентом использования диска.
  • Решения:
    • Добавьте больше дискового пространства: Самое простое решение — добавить больше хранилища на затронутые узлы или заменить существующие диски на более крупные.
    • Удалите неиспользуемые индексы: Выявите и удалите старые или ненужные индексы, которые занимают дисковое пространство.
    • Настройте водные метки: Вы можете настроить водные метки использования диска (cluster.routing.allocation.disk.watermark.low, cluster.routing.allocation.disk.watermark.high, cluster.routing.allocation.disk.watermark.flood_stage) в вашей конфигурации elasticsearch.yml или динамически через API настроек кластера. Однако, будьте осторожны при их настройке, так как они предназначены для защиты вашего кластера. Снижение их без увеличения емкости может привести к дальнейшим проблемам.
      json PUT _cluster/settings { "persistent": { "cluster.routing.allocation.disk.watermark.low": "85%", "cluster.routing.allocation.disk.watermark.high": "90%", "cluster.routing.allocation.disk.watermark.flood_stage": "95%" } }
    • Добавьте больше узлов: Масштабируйте ваш кластер, добавив больше узлов данных. Это распределит данные и уменьшит нагрузку на отдельные узлы.
    • Принудительное слияние или удаление старых данных: Если у вас есть данные временных рядов, рассмотрите возможность использования API _forcemerge для старых индексов, чтобы уменьшить количество сегментов (что может освободить дисковое пространство), или используйте управление жизненным циклом индекса (ILM) для автоматического удаления старых данных.

2. Узел недоступен или перезапускается

Если узел не работает, перезапускается или испытывает проблемы с сетью, любые шарды, находящиеся на этом узле, станут неназначенными. Если это первичный шард, статус кластера станет red (красным).

  • Симптом: Allocation Explain API укажет, что шард не может быть выделен, потому что узел недоступен или помечен как (excluded) из-за того, что он не работает.
  • Диагностика: Используйте API _cat/nodes для проверки состояния ваших узлов. Убедитесь, что все ожидаемые узлы перечислены и находятся в работоспособном состоянии.
    bash GET _cat/nodes?v
    Проверьте логи Elasticsearch на затронутом узле на наличие ошибок или признаков отключения.
  • Решения:
    • Перезапустите узел: Если узел не работает, попробуйте перезапустить службу Elasticsearch.
    • Устраните проблемы с сетью: Убедитесь, что узел может связываться с другими узлами в кластере.
    • Проверьте логи: Изучите логи Elasticsearch для конкретного узла, чтобы определить основную причину сбоя (например, нехватка памяти, ошибки диска, проблемы с JVM).
    • Увеличьте index.unassigned.node_left.delayed_timeout: Если узлы часто присоединяются к кластеру и покидают его (например, во время поэтапных перезапусков), вы можете заметить, что реплики шардов временно становятся неназначенными. Настройка index.unassigned.node_left.delayed_timeout (по умолчанию 1 минута) позволяет Elasticsearch подождать, прежде чем пометить шарды на покинувшем узел как неназначенные, давая узлу время для повторного присоединения. Увеличьте это значение при необходимости, но помните о влиянии на время восстановления.

3. Правила фильтрации выделения и осведомленности

Elasticsearch позволяет контролировать, где выделяются шарды, используя различные правила выделения, такие как атрибуты узлов и анти-аффинити. Если эти правила препятствуют выделению, шарды могут стать неназначенными.

  • Симптом: Allocation Explain API сообщит, что выделение отключено для определенных атрибутов или что нет подходящих узлов в соответствии с настроенными правилами.
  • Диагностика:
    • Проверьте настройки вашего индекса на предмет index.routing.allocation.require.*, index.routing.allocation.include.*, index.routing.allocation.exclude.* и index.routing.allocation.total_shards_per_node.
    • Проверьте настройки на уровне кластера для cluster.routing.allocation.enable (например, all, primaries, new_primaries, none).
    • Проверьте атрибуты узлов с помощью GET _cat/nodeattrs?v.
  • Решения:
    • Обновите настройки индекса: Удалите или скорректируйте ограничительные правила маршрутизации индекса. Например, чтобы разрешить выделение на любой узел:
      json PUT my-index/_settings { "index": { "routing": { "allocation": { "require": null, "include": null, "exclude": null } } } }
    • Обновите настройки кластера: Временно включите выделение, если оно было отключено:
      json PUT _cluster/settings { "persistent": { "cluster.routing.allocation.enable": "all" } }
      Не забудьте отменить эту настройку, если она предназначалась только для временного использования.
    • Обновите атрибуты узлов: Убедитесь, что ваши узлы имеют ожидаемые атрибуты, определенные в elasticsearch.yml (например, node.attr.zone: us-east-1), и что эти атрибуты соответствуют вашим правилам выделения. После изменения elasticsearch.yml узлы необходимо перезапустить, чтобы изменения вступили в силу.

4. Повреждение данных шарда (редко)

В редких случаях данные шарда могут быть повреждены, что препятствует запуску Elasticsearch или выделению шарда. Это чаще всего связано с проблемами на уровне диска.

  • Симптом: В логах могут отображаться ошибки, связанные с чтением данных шарда или повреждением индекса. Allocation Explain API может не дать четкой причины или указать на ошибку чтения.
  • Диагностика: Внимательно изучите логи Elasticsearch на узле, где предположительно находится шард. Ищите ошибки ввода-вывода или сообщения о повреждении данных.
  • Решения:
    • Восстановление из снимка: Самое надежное решение — восстановить затронутый индекс (или весь кластер) из заведомо рабочего снимка. Вот почему регулярные резервные копии критически важны.
    • Принудительное удаление шарда (крайняя мера): Если вы не можете восстановить данные из снимка, а данные не критичны или могут быть переиндексированы, вам может потребоваться принудительно удалить поврежденный шард. Это расширенная операция, и ее следует выполнять только тогда, когда вы понимаете последствия. Обычно требуется остановить затронутый узел, вручную удалить каталог данных шарда, а затем перезапустить узел. Это приведет к потере данных для этого шарда. Обратитесь к документации Elasticsearch для получения точной процедуры для вашей версии.

5. Недостаточная емкость для перемещения (relocation)

Когда узел покидает кластер или возникают проблемы с дисковым пространством, Elasticsearch пытается переместить шарды на другие узлы. Если подходящих узлов недостаточно или кластер уже находится под большой нагрузкой, перемещение шардов может застопориться, что приведет к initializing_shards или unassigned_shards.

  • Симптом: Шарды остаются в состоянии initializing (инициализации) или relocating (перемещения) в течение длительных периодов, или новые шарды не могут быть выделены.
  • Диагностика: Проверьте _cat/shards и _cat/allocation, чтобы увидеть статусы шардов и использование диска. Отслеживайте состояние кластера и загрузку CPU/IO узлов.
  • Решения:
    • Добавьте больше узлов: Увеличьте емкость вашего кластера, добавив больше узлов данных.
    • Освободите ресурсы: Устраните любые узкие места производительности на существующих узлах (например, высокая загрузка CPU, медленный ввод-вывод диска).
    • Настройте параметры выделения шардов: Вы можете настроить такие параметры, как cluster.routing.allocation.node_concurrent_recoveries (количество шардов, которые могут быть восстановлены одновременно на узле) и cluster.routing.allocation.node_concurrent_incoming_recoveries (количество шардов, которые могут быть восстановлены одновременно с другого узла). Однако будьте осторожны, так как увеличение этих значений может создать дополнительную нагрузку на кластер.

Рекомендации по предотвращению

  • Мониторинг дискового пространства: Активно отслеживайте использование диска на всех узлах данных. Настройте оповещения о превышении заданных порогов использования диска (например, 80% или 85%).
  • Внедрение управления жизненным циклом индекса (ILM): Автоматизируйте управление данными временных рядов, включая роллинг, сжатие и удаление старых индексов. Это помогает контролировать использование дискового пространства.
  • Регулярные снимки: Убедитесь, что у вас есть надежная стратегия резервного копирования с регулярными, автоматизированными снимками ваших данных. Периодически тестируйте процесс восстановления.
  • Понимание правил выделения: Тщательно планируйте и настраивайте правила выделения шардов на основе вашего оборудования, данных и требований к доступности.
  • Адекватное оборудование: Убедитесь, что ваши узлы имеют достаточные возможности CPU, RAM и I/O для обработки рабочей нагрузки и процессов восстановления шардов.
  • Мониторинг состояния кластера: Регулярно проверяйте состояние вашего кластера с помощью API _cluster/health и визуализируйте его с помощью таких инструментов, как Kibana Stack Monitoring.

Заключение

Сбои при выделении шардов в Elasticsearch могут быть серьезной проблемой, но, систематически диагностируя ее с помощью таких инструментов, как Cluster Health API и Allocation Explain API, и понимая распространенные причины, такие как дисковое пространство, доступность узлов и правила выделения, вы сможете эффективно их устранять. Проактивный мониторинг и соблюдение лучших практик, таких как регулярное резервное копирование и ILM, являются ключом к предотвращению этих проблем в первую очередь и обеспечению стабильного, здорового кластера Elasticsearch.