Подтвердить что ты не робот

Понимание потребности в сельдерее

Я только что узнал о параметре конфигурации CELERYD_PREFETCH_MULTIPLIER (docs). По умолчанию 4, но (я считаю), я хочу, чтобы предварительная выборка была как можно более низкой. Я установил его в 1 сейчас, что достаточно близко к тому, что я ищу, но все же некоторые вещи я не понимаю:

  • Почему эта предварительная выборка хорошая идея? Я действительно не вижу причины для этого, если между очередью сообщений и рабочими не существует много задержек (в моем случае они в настоящее время работают на одном и том же хосте, а в худшем случае могут запускаться на разных хостах в одних и тех же данных центр). В документации упоминаются только недостатки, но не объясняется, какие преимущества существуют.

  • Многие люди, похоже, задают это значение 0, ожидая, что смогут отключить предварительную выборку (разумное предположение, на мой взгляд). Однако 0 означает неограниченную предварительную выборку. Зачем кому-либо когда-либо требовалась неограниченная предварительная выборка, не полностью ли исключает concurrency/асинхронность, в которой вы ввели очередь задач?

  • Почему предварительная выборка не может быть отключена? Возможно, неплохо было бы заставить производительность отключить его в большинстве случаев, но есть ли техническая причина, по которой это невозможно? Или это просто не реализовано?

  • Иногда этот параметр подключается к CELERY_ACKS_LATE. Например. Роджер Ху пишет "[...] часто, что [пользователи] действительно хотят, чтобы у рабочего оставалось столько задач, сколько есть дочерние процессы. Но это невозможно без включения поздних подтверждений [...]" Я не понимаю, как эти два параметра связаны и почему одно невозможно без другого. Еще одно упоминание о связи можно найти здесь. Может кто-нибудь объяснить, почему эти два параметра связаны?

4b9b3361

Ответ 1

  • Предварительная выборка может улучшить производительность. Рабочим не нужно ждать следующего сообщения от брокера для обработки. Коммуникация с брокером один раз и обработка большого количества сообщений дает прирост производительности. Получение сообщения от брокера (даже с локального) является дорогостоящим по сравнению с доступом к локальной памяти. Рабочим также разрешено принимать сообщения в пакетах

  • Предварительная выборка, установленная на ноль, означает "без определенного предела", а не неограниченно

  • Настройка предварительной выборки до 1 документально эквивалентна отключению, но это может быть не всегда (см. fooobar.com/questions/112539/...)

  • Предварительная выборка позволяет отправлять сообщения пакетами. CELERY_ACKS_LATE = True предотвращает подтверждение сообщений, когда они достигают рабочего

Ответ 2

Просто предупреждение: по моему тестированию с броузером redis + Celery 3.1.15 все советы, которые я прочитал, относятся к отключению предварительной выборки CELERYD_PREFETCH_MULTIPLIER = 1. Это явно ложно.

Чтобы продемонстрировать это:

  • Установить CELERYD_PREFETCH_MULTIPLIER = 1
  • Очередь 5 задач, каждая из которых займет несколько секунд (например, time.sleep(5))
  • Начните просмотр длины очереди задач в Redis: watch redis-cli -c llen default

  • Запустить celery worker -c 1

  • Обратите внимание, что длина очереди в Redis будет немедленно снижаться с 5 до 3

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 несовместимо с предварительной выборкой. Теоретически, предварительная выборка все же позволила бы заполучить поздний правый - даже если бы он не был закодирован как таковой в сельдерее?