Клиент Python для Elasticsearch не удаляет мёртвый узел

Вопрос или проблема

У нас есть кластер из 6 экземпляров Elasticsearch (версия 8.13), управляемый с помощью Docker Swarm в Google Cloud. У нас есть несколько индексов с 2 репликами каждый. Нам нужно было обновить наш кластер (увеличить объем памяти), поэтому план состоял в том, чтобы выключить один экземпляр, увеличить объем памяти, перезапустить его и повторить это для каждого другого экземпляра.

Конфигурация клиента выглядит следующим образом:

  hosts:
    - scheme: http
      host: "es8_node"
      port: 9200
  timeout: 10
  sniff_on_start: True
  sniff_on_node_failure: True
  sniff_timeout: 15

Когда первый экземпляр вернулся к работе, здоровье кластера быстро восстановилось до 100%, и все шардов были назначены, но время ответа по некоторым запросам все еще оставалось очень высоким.

Даже через час некоторые запросы по-прежнему имели очень высокое время отклика, но мне удалось найти эту запись в логах Python-сервиса:

Узел <Urllib3HttpNode(http://10.0.3.53:9200)> потерпел неудачу 271 раз подряд, выставив 30-секундный тайм-аут.

Оказалось, что экземпляр, который я перезапустил, получил новый IP-адрес, и даже после стольких сбоев он не был удален из списка узлов. Почему? Эти повторные попытки и восстановление этого узла вызывали высокое время ответа.

Разве sniff_on_node_failure не должен был решить эту проблему? В списке узлов, который я получаю из Elasticsearch (_cat/nodes), этот узел больше не указан. Почему он не был удален?

Ответ или решение

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

Причина проблемы

Когда вы восстановили первый узел и он по какой-то причине получил новый IP-адрес, возможно, вы столкнулись с несколькими проблемами. Несмотря на то, что узел не отображается в результате команды _cat/nodes, клиент Python все еще считает его активным в течение определенного времени из-за механизма, который управляет статусом узлов.

Код ошибки, который вы видите в логах — Node <Urllib3HttpNode(http://10.0.3.53:9200)> has failed for 271 times in a row, putting on 30 second timeout — говорит о том, что клиент не может подключиться к узлу, который по каким-то причинам стал недоступен. Здесь важно понимать, что клиент Python имеет встроенные таймауты и механизм повторных попыток, которые позволяют ему продолжать попытки подключения к несуществующему или недоступному узлу.

Почему sniff_on_node_failure не срабатывает?

Опция sniff_on_node_failure предназначена для повторного сканирования узлов, чтобы обновить их список при первом неудачном подключении. Однако в вашем случае, если клиент не получает ответ от узла по IP-адресу в течение определенного времени, он может не инициировать повторный "снифф" узлов. Невозможность подключения может приводить к тому, что произошли тайм-ауты, и функция sniff_on_node_failure не будет вызвана.

Решения

  1. Увеличьте тайм-ауты на клиенте: Вы можете попробовать увеличить значения параметров timeout и sniff_timeout, чтобы дать клиенту больше времени для проверки доступности узла.

  2. Используйте статические IP-адреса: Если возможно, рассмотрите возможность присвоения статических IP-адресов вашим контейнерам Elasticsearch, чтобы избежать проблем, связанных с изменением IP-адресов при перезапуске.

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

    from elasticsearch import Elasticsearch
    
    es = Elasticsearch(
       hosts=[{"host": "es8_node", "port": 9200}],
       timeout=10,
       sniff_on_start=True,
       sniff_on_node_failure=True,
       sniff_timeout=15
    )
    es.transport.sniff()  # Сбросьте информацию о узлах вручную
  4. Мониторинг и алерты: Настройте мониторинг и алерты для узлов Elasticsearch с использованием инструментов вроде Kibana или Prometheus, чтобы более быстро реагировать на подобные инциденты.

Заключение

Исходя из вышесказанного, ваша проблема связана с механизмом управления узлами в клиенте Python. Увеличение тайм-аутов, использование статических IP-адресов и ручная профилактика через метод sniff() могут помочь вам избежать подобного поведения в будущем.

Оцените материал
Добавить комментарий

Капча загружается...