Понимание потребности в сельдерее
Я только что узнал о параметре конфигурации CELERYD_PREFETCH_MULTIPLIER
(docs). По умолчанию 4, но (я считаю), я хочу, чтобы предварительная выборка была как можно более низкой. Я установил его в 1 сейчас, что достаточно близко к тому, что я ищу, но все же некоторые вещи я не понимаю:
-
Почему эта предварительная выборка хорошая идея? Я действительно не вижу причины для этого, если между очередью сообщений и рабочими не существует много задержек (в моем случае они в настоящее время работают на одном и том же хосте, а в худшем случае могут запускаться на разных хостах в одних и тех же данных центр). В документации упоминаются только недостатки, но не объясняется, какие преимущества существуют.
-
Многие люди, похоже, задают это значение 0, ожидая, что смогут отключить предварительную выборку (разумное предположение, на мой взгляд). Однако 0 означает неограниченную предварительную выборку. Зачем кому-либо когда-либо требовалась неограниченная предварительная выборка, не полностью ли исключает concurrency/асинхронность, в которой вы ввели очередь задач?
-
Почему предварительная выборка не может быть отключена? Возможно, неплохо было бы заставить производительность отключить его в большинстве случаев, но есть ли техническая причина, по которой это невозможно? Или это просто не реализовано?
-
Иногда этот параметр подключается к CELERY_ACKS_LATE
. Например. Роджер Ху пишет "[...] часто, что [пользователи] действительно хотят, чтобы у рабочего оставалось столько задач, сколько есть дочерние процессы. Но это невозможно без включения поздних подтверждений [...]" Я не понимаю, как эти два параметра связаны и почему одно невозможно без другого. Еще одно упоминание о связи можно найти здесь. Может кто-нибудь объяснить, почему эти два параметра связаны?
Ответы
Ответ 1
-
Предварительная выборка может улучшить производительность. Рабочим не нужно ждать следующего сообщения от брокера для обработки. Коммуникация с брокером один раз и обработка большого количества сообщений дает прирост производительности. Получение сообщения от брокера (даже с локального) является дорогостоящим по сравнению с доступом к локальной памяти. Рабочим также разрешено принимать сообщения в пакетах
-
Предварительная выборка, установленная на ноль, означает "без определенного предела", а не неограниченно
-
Настройка предварительной выборки до 1 документально эквивалентна отключению, но это может быть не всегда (см. fooobar.com/questions/112539/...)
-
Предварительная выборка позволяет отправлять сообщения пакетами. CELERY_ACKS_LATE = True предотвращает подтверждение сообщений, когда они достигают рабочего
Ответ 2
Просто предупреждение: по моему тестированию с броузером redis + Celery 3.1.15 все советы, которые я прочитал, относятся к отключению предварительной выборки CELERYD_PREFETCH_MULTIPLIER = 1
. Это явно ложно.
Чтобы продемонстрировать это:
CELERYD_PREFETCH_MULTIPLIER = 1
не предотвращает предварительную выборку, она просто ограничивает предварительную выборку до 1 задачи на каждую очередь.
-Ofair
, несмотря на то, что говорится в документации, также не предотвращает предварительную выборку.
За исключением изменения исходного кода, я не нашел никакого способа полностью отключить предварительную выборку.
Ответ 3
Старый вопрос, но все равно добавляю мой ответ, если он кому-то помогает. Мое понимание от начального тестирования было таким же, как в ответе Дэвида Волевера. Я просто испытал это больше в сельдере 3.1.19 и -Ofair действительно работает. Просто он не предназначен для отключения предварительной выборки на уровне рабочего node. Это будет продолжаться. Использование -Ofair имеет другой эффект, который находится на уровне рабочего пула. Итак, чтобы полностью отключить предварительную выборку, сделайте это -
- Установить
CELERYD_PREFETCH_MULTIPLIER = 1
- Установите
CELERY_ACKS_LATE = True
на глобальном уровне или уровне задачи
- Используйте
-Ofair
при запуске рабочих
- Если вы установили concurrency в 1, то шаг 3 не нужен. Если вы хотите
выше concurrency, то шаг 3 необходим, чтобы избежать
резервное копирование в node, которое может запускаться с запущенными задачами.
Добавление дополнительных сведений:
Я обнаружил, что рабочий node всегда будет префектом по умолчанию. Вы можете контролировать только количество заданий, которые он префикс, используя CELERYD_PREFETCH_MULTIPLIER
. Если установлено значение 1, оно будет только предварять столько задач, сколько количество рабочих пулов (concurrency) в node. Поэтому, если у вас есть concurrency= n, максимальные задачи, предварительно запрограммированные node, будут n.
Без опции -Ofair
для меня случилось то, что если один из рабочих процессов пула выполнял многолетнюю задачу, другие работники в node также прекратили обработку задач, уже запрограммированных с помощью node. Используя -Ofair
, это изменилось. Несмотря на то, что один из рабочих в node выполнял длительные задачи, другие не прекращали обработку и продолжали обрабатывать задачи, предварительно запрограммированные node. Поэтому я вижу два уровня предварительной выборки. Один на уровне рабочего node. Другое - на уровне отдельных работников. Использование -Ofair
для меня, казалось, отключило его на рабочем уровне.
Как ACKS_LATE
связано? ACKS_LATE = True
означает, что задача будет подтверждена только тогда, когда задача выполнена успешно. Если нет, я полагаю, что это произойдет, когда он будет получен работником. В случае предварительной выборки задача сначала получает рабочий (подтверждается из журналов), но будет выполнена позже. Я только осознал, что сообщения, предварительно записанные в память, появляются под непризнанными сообщениями в rabbitmq. Поэтому я не уверен, что установка True на True абсолютно необходима. В любом случае, наши задачи были поставлены таким образом (по-последнему) по другим причинам.
Ответ 4
Я не могу комментировать ответы Дэвида Волевера, так как мой stackcred недостаточно высок. Итак, я сформулировал свой комментарий как ответ, так как хотел бы поделиться своим опытом с Celery 3.1.18 и брокером Mongodb. Мне удалось остановить предварительную выборку со следующим:
- добавить
CELERYD_PREFETCH_MULTIPLIER = 1
в конфигурацию сельдерея
- добавить
CELERY_ACKS_LATE = True
в конфигурацию сельдерея
- Начните работника сельдерея с опциями:
--concurrency=1 -Ofair
По умолчанию для CELERY_ACKS_LATE, рабочий по-прежнему предварительно выбирает. Точно так же, как OP, я не полностью понимаю связь между предварительной выборкой и поздними настройками. Я понимаю, что говорит Дэвид: "CELERY_ACKS_LATE = True предотвращает подтверждение сообщений, когда они доходят до рабочего", но я не понимаю, почему late acks несовместимо с предварительной выборкой. Теоретически, предварительная выборка все же позволила бы заполучить поздний правый - даже если бы он не был закодирован как таковой в сельдерее?