Как контролировать состояние очереди в сельдерее
У меня есть следующая настройка:
- Общий рабочий пул с 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.