Будет ли параллельное выполнение при запуске длинного таска в Celery с передачей управления группе
Что проверяют
Понимаете ли вы, откуда в Celery берётся параллельность и что будет, если задача запускает группу подзадач и ждёт их. Следом почти всегда спрашивают, почему вызывать result.get() внутри задачи нельзя и чем это заменить.
Как отвечать
group() сама ничего не распараллеливает. Она кладёт в брокер отдельное сообщение на каждую подпись, а выполняются они параллельно ровно настолько, насколько есть свободных исполнителей. Это задают параметры воркера:
--concurrency: число процессов или потоков, по умолчанию равно числу ядер;--pool:preforkдаёт настоящую параллельность процессами,threads,gevent,eventletподходят для задач, ждущих ввода-вывода, аsoloвыполняет всё строго по одной;- prefetch: процесс заранее резервирует задачи (
worker_prefetch_multiplier, по умолчанию 4). Для длинных задач ставят 1 вместе сtask_acks_late=True, иначе короткие задачи ждут за длинной в чужом резерве.
Теперь сам сценарий. Если длинная задача запускает группу и ждёт её через .get(), она держит слот воркера. Когда все слоты заняты такими родителями, дочерним задачам негде выполняться, и система встаёт. Поэтому Celery по умолчанию бросает RuntimeError при вызове get() внутри задачи. Обойти можно через disable_sync_subtasks=False, но это обход, а не решение.
Правильно не ждать, а описать продолжение:
chord(header)(callback): подзадачи идут параллельно, колбэк получает список результатов, когда все закончились. Нужен result backend, например Redis;self.replace(...): задача заменяет себя группой или chord, и следующий шаг цепочки дождётся их результата;chain: если шаги зависят друг от друга последовательно.
Длинные задачи удобно вынести в отдельную очередь с отдельным воркером, чтобы они не забивали быстрые.
Где спотыкаются
Отвечают «да, группа всегда параллельна». При --concurrency=1 или пуле solo подзадачи пойдут одна за другой.
Ждут результат внутри задачи и получают взаимную блокировку под нагрузкой, хотя на стенде с запасом процессов всё работало.
Путают Celery Beat с воркерами. Beat только ставит задачи по расписанию и параллельности не добавляет.