Как контролировать состояние очереди в сельдерее

У меня есть следующая настройка:

  • Общий рабочий пул с 100 рабочими
  • Высокопоставленный рабочий пул с 50 рабочими
  • Я использовал такие большие числа, потому что большую часть времени мои задачи тратят ожидания ввода-вывода с очень длинными таймаутами (выполнение HTTP-запросов, на которые может отвечать до 20 секунд)
  • Использование RabbitMQ в качестве брокера
  • Я установил celeryd как deamon, используя скрипты init.d из gellub celery'd со следующими параметрами: CELERYD_OPTS="--time-limit=600 -c:low_p 100 -c:high_p 50 -Q:low_p low_priority_queue_name -Q:high_p high_priority_queue_name"

Моя проблема заключается в том, что иногда очередь кажется "резервной", то есть она перестанет потреблять задачи. Кажется, для этого есть сценарии:

  • В брокере наблюдается медленное наращивание "неподтвержденных" сообщений, хотя celery inspect active покажет, что не все рабочие израсходованы, то есть я увижу только несколько активных задач
  • Очередь просто перестанет потреблять новые задачи без наращивания.
  • Когда в "мертвом" состоянии использование strace на рабочих процессах ничего не возвращает... полностью нулевая активность от рабочего

Буду признателен за любую информацию или указатели на:

  • Как я могу его отладить. Я могу использовать strace, чтобы посмотреть, что делают рабочие процессы, но до сих пор было полезно сообщить мне, что рабочий висит
  • Как я могу контролировать это, и возможно сделать автовосстановление. Существует множество инструментов для управления сельдереем (flower и events, но они оба превосходны в режиме реального времени, но не имеют никакой функции автоматического мониторинга/предупреждения). Мне просто лучше писать собственные инструменты мониторинга с помощью supervisord?

Кроме того, я начинаю свои задания с django-celery

Ответ 1

Очень простой сторожевой таймер может быть реализован только с одним script, который запускается каждую минуту cron. Во-первых, он запускает задачу, которая при выполнении (у рабочего) затрагивает предопределенный файл, например:

with open('/var/run/celery-heartbeat', 'w'):
    pass

Затем script проверяет метку времени модификации на этом файле и, если ее больше минуты (или 2 минуты или что-то еще), отправляет сигнал тревоги и/или перезапускает рабочих и/или брокера.

Это немного сложнее, если у вас несколько компьютеров, но эта же идея применяется.

Ответ 2

@goro, если вы делаете запросы к иностранным сервисам, вы должны попробовать gevent или eventlet реализовать пул вместо появления 100500 рабочих. У меня также была проблема, когда работники сельдерея перестали выполнять задачи, это было вызвано ошибкой сельдерей + gevent + часовой (ворон).

Одна вещь, которую я выясняю в Celery, заключается в том, что она может работать нормально, без какого-либо мониторинга, если все будет сделано правильно (в настоящее время я выполняю > 50M задач в день), но если это не так, мониторинг не поможет вам. "Восстановление после стихийных бедствий" в Сельдерей немного сложнее, не все будет работать так, как вы ожидаете: (

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

Ответ 3

Я бы подумал, что это связано с тем, что работники заранее задают задачи. Если это проблема, вы можете обновить сельдерей до версии 3.1 и использовать параметр -Ofair worker. Параметр конфигурации, который я пытался использовать до -Ofair, был CELERYD_PREFETCH_MULTIPLIER. Однако установка CELERYD_PREFETCH_MULTIPLIER = 1 (ее минимальное значение) не помогает, так как работники будут предварительно предварительно запускать одну задачу.

См. http://docs.celeryproject.org/en/latest/whatsnew-3.1.html#prefork-pool-improvements и особенно http://docs.celeryproject.org/en/latest/whatsnew-3.1.html#caveats.