Ответ
По умолчанию Celery использует процессы (модель prefork), а не потоки. Это основной и наиболее стабильный способ параллельного выполнения задач.
Почему процессы, а не потоки?
- Обход Global Interpreter Lock (GIL) в Python: GIL не позволяет нескольким нативным потокам одновременно выполнять Python-байткод. Использование отдельных процессов позволяет полностью утилизировать все ядра CPU для CPU-bound задач.
- Изоляция: Сбой в одной задаче (например, ошибка сегментации) не повлияет на другие задачи, так как они выполняются в изолированных процессах.
Доступные модели параллелизма (пулы):
Celery позволяет изменять пул выполнения с помощью флага -P (--pool).
prefork(по умолчанию): Пул процессов. Идеально для задач, интенсивно использующих CPU.gevent/eventlet: Используют "зеленые" потоки (greenlets). Отлично подходят для I/O-bound задач (например, сетевые запросы, работа с файлами), так как могут обрабатывать тысячи одновременных задач с минимальными накладными расходами.threads: Пул нативных потоков ОС. Может быть полезен для I/O-bound задач, если использованиеgeventилиeventletпо каким-то причинам невозможно. Считается менее надежным, чемprefork.
Пример запуска worker с пулом gevent:
# Запуск worker с 1000 greenlets для обработки I/O-задач
celery -A my_project worker -P gevent --concurrency=1000 -l info