Celery 4 с RabbitMQ очень медленно буферизует задачи ETA при запуске - PullRequest
0 голосов
/ 10 марта 2019

Context

Я недавно начал пытаться обновить Celery с 3.1.25 до 4.2.1.Мы используем Python 2.7.6, бэкэнд RabbitMQ (3.6) и драйвер pyamqp.

Мы запускаем сельдерей с отключенными pidbox, наряду с --without-mingle, --without-gossip и --without-heartbeatoptions.

У нас есть одна очередь, которая содержит только один тип задачи: задача ETA со временем выполнения в далеком (днях) будущем.Каждое задание выполняется за <1 мс, и они редко «приходят из-за».По большей части эти работники сидят и буферизуют задачи ETA в состоянии ETA, ожидая прибытия новой или время от времени ее выполнения. </p>

Несколько работников (параллелизм 1, prefork) прослушивают эту очередь.Для этих работников CELERYD_PREFETCH_MULTIPLIER установлено значение 50.

Обычно, когда эти работники перезапускаются, задачи в RabbitMQ доставляются в очень короткие сроки.Через несколько минут или меньше: все задачи покидают состояние «готово» и остаются рабочими в «незанятом» состоянии.

Ранее, когда для CELERYD_PREFETCH_MULTIPLIER было установлено значение 1, это занимало очень много времени.время для рабочих для буферизации задач (рабочие постепенно увеличивают свое QoS и RabbitMQ, впоследствии распределяя эти задачи среди рабочих и переводя их в незанятое состояние).После того как мы установили его на 50, процесс ребуферизации для очереди из 10 000 задач выглядит в RabbitMQ следующим образом:

enter image description here

Сразу после того, как все задачи были буферизованы,Celery начинает выполнять (очень мало) задач, для которых требуется ETA.

Задача

После обновления с сельдерея с 3.1.25 до 4.2.1, когда рабочие ETA перезапускаются, требуется оченьCelery долгое время увеличивал размер буфера QoS, чтобы перевести все сообщения в состояние «без упаковки» (и во внутреннюю очередь кучи для проверки ETA).Это занимает так много времени, что некоторые из ETA задач пропускаются.

Celery 4 увеличивает окно QoS намного медленнее (хотя оно неуклонно увеличивается), чем версия 3.

Я могучтобы реплицировать эту ситуацию локально на моем ноутбуке (с очередью, полной задач ETA, время прибытия которых составляет дни в будущем), а также на производстве.Сельдерей 3, кажется, увеличивает свое QoS и время от времени спит, но не очень долго.Сельдерей 4 также увеличивает QoS, но, по-видимому, спит гораздо чаще и дольше.Даже в режиме отладки информация не выдается, когда рабочие спят.

В этом тесте поведение Celery 4 выглядит следующим образом:

enter image description here

(Приход сообщений в 20:02 - это заполнение очереди задачами ETA перед запуском работника и началом теста).

Единственное, что изменяется между этими поведениями, - это версия Celery.

Это вызывает проблемы в работе, потому что, хотя работники могут быть недоступны в течение нескольких минут, а когда они перезапускаются (например, из-за развертывания кода), очень глубокие очереди только для ETA могут занять часы для повторной доставкирабочим.В течение этого времени задачи, чьи ETA находятся в прошлом, могут не подниматься.

Вопросы

  • Почему доставка задач на основе предварительной выборки из очереди, содержащей только задачи ETA с будущимВ Celery 4 время прибытия намного медленнее, чем в Celery 3?
  • Как можно восстановить поведение Celery 3, если не считать понижения?

Что я пробовал

  • Обойти проблему, увеличив параллель.Производственная очередь только для ETA часто запускается с общим числом сообщений более 100 тыс. И параллельно с параллельным использованием 4 процессов (каждый из которых является --concurrency=1 рабочим Celery на другом хосте).На Celery 3 общее время простоя / позднего ETA с 4 рабочими составило около 3 минут.На Celery 4 мы пытались увеличить число рабочих до 64, и очереди все еще требовалось более часа, чтобы достичь 0 сообщений в состоянии готовности.
  • Если посмотреть на источник Celery, ограничения скорости могут быть связаны сэта ситуация.Запуск Celery с CELERY_DISABLE_RATE_LIMITS не повлиял на поведение.
  • Я пытался установить CELERYD_PREFETCH_MULTIPLIER на 0 для затронутых работников.Это решает проблему (задачи перераспределяют задачи даже быстрее, чем в Celery 3), но создает худшую проблему: некоторые работники часто выходят из строя и исчерпывают память, пока система не достигнет равновесия между различными потребителями на разных хостах.Это создает сбои в мониторинге и много шума, и, если нет другой альтернативы, я бы не хотел полагаться на то, что работники «мчатся», чтобы получать сообщения как можно быстрее.Использование множителя с высоким значением, по крайней мере, в Celery 3, позволило нам по совпадению распределить ожидающие ETA сообщения более или менее равномерно по всем потребителям в кластере.
    • Я попытался вернуться к планировщику -OFast (Celery 4 изменил значение по умолчанию).Это не имело никакого эффекта.
    • Изменение значения CELERYD_TIMER_PRECISION также не имело никакого эффекта.
...