Что такое Celery и для чего он нужен
Что проверяют
Понимаете ли вы, зачем выносить работу из HTTP-запроса в фон и какие гарантии Celery даёт на самом деле. Следом обычно спрашивают, что будет с задачей, если воркер упадёт посреди выполнения, и как сделать повтор безопасным.
Как отвечать
Celery это распределённая очередь задач для Python. Приложение (Django, FastAPI, скрипт) кладёт сообщение о задаче в брокер, отдельные процессы-воркеры забирают его и выполняют. С asyncio это не связано: по умолчанию воркер работает пулом процессов prefork.
Компоненты:
- задача: функция с
@app.taskили@shared_task, ставится в очередь черезdelay()илиapply_async(countdown=60); - брокер: RabbitMQ или Redis, реже Amazon SQS. Хранит очередь, но не результаты;
- воркер:
celery -A proj worker, параллелизм задаёт--concurrency, задачи разводят по очередям черезtask_routes; - result backend: Redis или база, нужен, только если вы читаете результат или строите
chord; - beat: планировщик периодических задач, отдельный процесс строго в одном экземпляре.
Типичные применения: письма и уведомления, отчёты и PDF, обработка загруженных файлов, медленные внешние API, ночные пересчёты.
Про надёжность стоит сказать сразу. По умолчанию сообщение подтверждается до выполнения, и если воркер умер посреди задачи, она потеряна. acks_late=True переносит подтверждение на конец, но тогда задача может выполниться дважды, значит, она обязана быть идемпотентной. Повторы настраивают через autoretry_for, retry_backoff и max_retries.
Для asyncio-стека есть варианты полегче, например Taskiq или arq, для простых случаев хватает RQ.
Где спотыкаются
Передают в задачу ORM-объект. JSON-сериализатор его не примет, а через pickle уедет устаревший снимок. Передавать нужно id и перечитывать запись внутри задачи.
Ставят задачу внутри транзакции Django. Воркер стартует раньше коммита и не находит только что созданную строку. Постановку оборачивают в transaction.on_commit, с Celery 5.4 для этого есть delay_on_commit().
Не знают про visibility_timeout у брокера Redis: задача с countdown или eta дальше этого окна (по умолчанию час) будет доставлена повторно.