Я только что узнал о параметре конфигурации CELERYD_PREFETCH_MULTIPLIER
( документы ). По умолчанию - 4, но (я считаю) я хочу, чтобы предварительная выборка была отключена или как можно меньше. Сейчас я установил его на 1, что достаточно близко к тому, что я ищу, но есть еще кое-что, чего я не понимаю:
Почему это хорошая идея? Я действительно не вижу для этого причины, если только нет большой задержки между очередью сообщений и рабочими (в моем случае они в настоящее время работают на одном хосте и в худшем случае могут в конечном итоге работать на разных хостах с одними и теми же данными. центр). В документации упоминаются только недостатки, но не объясняются преимущества.
Многие люди, кажется, устанавливают это значение в 0, ожидая, что таким образом можно будет отключить предварительную выборку (разумное предположение, на мой взгляд). Однако 0 означает неограниченную предварительную выборку. Зачем кому-то нужна неограниченная предварительная выборка, разве это не устраняет полностью параллелизм / асинхронность, для которой вы в первую очередь ввели очередь задач?
Почему нельзя отключить предварительную выборку? В большинстве случаев это может быть не лучшим решением для производительности, но есть ли техническая причина, по которой это невозможно? Или это просто не реализовано?
Иногда эта опция связана с
CELERY_ACKS_LATE
. Например. Роджер Ху пишет: «[…] часто на самом деле [пользователи] действительно хотят, чтобы рабочий зарезервировал столько задач, сколько дочерних процессов. Но это невозможно без включения поздних подтверждений […] »Я не понимаю, как связаны эти два варианта и почему одно невозможно без другого. Еще одно упоминание о связи можно найти здесь . Может кто-нибудь объяснить, почему эти два варианта связаны?
CELERYD_PREFETCH_MULTIPLIER = 1
делает не отключить предварительную выборку. Он просто - как следует из названия - выполняет предварительную выборку только одной задачи за раз.Старый вопрос, но все еще добавляю свой ответ, если это кому-то поможет. Мое понимание из некоторого начального тестирования было таким же, как и в ответе Дэвида Волевера. Я только что проверил это больше в сельдерее 3.1.19 и
-Ofair
действительно работает. Просто он не предназначен для отключения предварительной выборки на уровне рабочего узла. Так будет и дальше. Использование-Ofair
имеет другой эффект, который проявляется на уровне работника пула. Таким образом, чтобы полностью отключить предварительную выборку, сделайте следующее:CELERYD_PREFETCH_MULTIPLIER = 1
CELERY_ACKS_LATE = True
на глобальном уровне или уровне задачи-Ofair
при запуске рабочихДобавляем еще несколько деталей:
Я обнаружил, что рабочий узел всегда выполняет предварительную выборку по умолчанию. Вы можете контролировать, сколько задач он предварительно выбирает, только используя
CELERYD_PREFETCH_MULTIPLIER
. Если установлено значение 1, он будет выполнять предварительную выборку только столько задач, сколько рабочих пула (параллелизм) в узле. Итак, если у вас есть concurrency = n, максимальное количество задач, предварительно загружаемых узлом, будет n.Без этой
-Ofair
опции для меня произошло следующее: если один из рабочих процессов пула выполнял длительную задачу, другие рабочие в узле также перестали бы обрабатывать задачи, уже предварительно загруженные узлом. При использовании-Ofair
, что изменилось. Даже если один из рабочих в узле выполнял длительные задачи, другие не прекращали обработку и продолжали обрабатывать задачи, предварительно загруженные узлом. Итак, я вижу два уровня предварительной выборки. Один на уровне рабочего узла. Другой - на уровне отдельного работника. Использование-Ofair
для меня, казалось, отключило его на рабочем уровне.Как это
ACKS_LATE
связано?. Я только что понял, что предварительно загруженные сообщения отображаются в rabbitmq в разделе «неподтвержденные сообщения». Поэтому я не уверен, что установка этого значенияACKS_LATE = True
означает, что задача будет подтверждена только в случае успешного выполнения задачи. Если нет, я полагаю, это произойдет, когда его получит рабочий. В случае предварительной выборки задача сначала получает рабочий (подтверждается из журналов), но будет выполнена позжеTrue
абсолютно необходима. У нас все равно были поставлены задачи таким образом (позднее подтверждение) по другим причинам.источник
-Ofair
имеет «другой эффект», но не то, как этот эффект отличается. Кроме того, вы поднимаете вопросCELERY_ACKS_LATE
, как и другие раньше, но пока никому не удалось объяснить мне, какое отношение этот атрибут имеет к отключению предварительной выборки.prefetch=1, celery_acks=True
и когда я добавил,-Ofair
исправлена проблема, когда они ждали зависшего рабочего. К сожалению, проблема с зависшими рабочими по-прежнему не решена для меня, поэтому все рабочие в конечном итоге зависают, но по крайней мере они больше не делают это в одно и то же время.Просто предупреждение: на момент моего тестирования с брокером redis + Celery 3.1.15 все советы, которые я прочитал, относящиеся к
CELERYD_PREFETCH_MULTIPLIER = 1
отключения предварительной выборки, явно неверны.Чтобы продемонстрировать это:
CELERYD_PREFETCH_MULTIPLIER = 1
time.sleep(5)
)Начните следить за длиной очереди задач в Redis:
watch redis-cli -c llen default
Начало
celery worker -c 1
5
до3
CELERYD_PREFETCH_MULTIPLIER = 1
не препятствует предварительной выборке , а просто ограничивает предварительную выборку до 1 задачи на очередь.-Ofair
, несмотря на то, что говорится в документации , также не предотвращает предварительную выборку .Если не считать изменения исходного кода, я не нашел никакого способа полностью отключить предварительную выборку.
источник
CELERY_ACKS_LATE = 1
вы эффективно отключите предварительную выборку.Я не могу комментировать ответы Дэвида Волевера, поскольку мой стек недостаточно высок. Итак, я сформулировал свой комментарий как ответ, так как хотел бы поделиться своим опытом работы с Celery 3.1.18 и брокером Mongodb. Мне удалось остановить предварительную выборку следующим образом:
CELERYD_PREFETCH_MULTIPLIER = 1
в конфиг сельдереяCELERY_ACKS_LATE = True
в конфиг сельдерея--concurrency=1 -Ofair
Если оставить значение CELERY_ACKS_LATE по умолчанию, рабочий процесс по-прежнему выполняет предварительную выборку. Как и в случае с OP, я не совсем понимаю связь между предварительной выборкой и поздним подтверждением. Я понимаю, что говорит Дэвид: «CELERY_ACKS_LATE = True предотвращает подтверждение сообщений, когда они доходят до рабочего», но я не понимаю, почему поздние подтверждения несовместимы с предварительной выборкой. Теоретически упреждающая выборка по-прежнему позволяла бы подтверждать позднее право, даже если она не закодирована как таковая в сельдерее?
источник
С SQS в качестве брокера я испытал кое-что немного другое.
Настройка была:
CELERYD_PREFETCH_MULTIPLIER = 1 ACKS_ON_FAILURE_OR_TIMEOUT=False CELERY_ACKS_LATE = True CONCURRENCY=1
После сбоя задачи (возникло исключение) рабочий стал недоступен, так как сообщение не было подтверждено как в локальной, так и в удаленной очереди.
Решение, которое заставляло рабочих продолжать трудиться, заключалось в установке
CELERYD_PREFETCH_MULTIPLIER = 0
Я могу только предположить, что acks_late не принимался во внимание при написании транспорта SQS.
источник