PRO

Как настроить Celery с приоритетами очередей?

Приоритеты позволяют выполнять срочные задачи раньше фоновых и менее важных. В Celery это можно организовать отдельными очередями для разных классов задач или использовать нативные приоритеты брокера, если он их поддерживает; RabbitMQ поддерживает очереди с приоритетами, а Redis обычно требует модели с несколькими очередями.
Подробный ответ

Почему одной очереди недостаточно

Если срочные уведомления, обработка пользовательских запросов и тяжёлые отчёты находятся в одной очереди, отчёты могут занять всех исполнителей. Пользовательские действия будут ждать, хотя сами выполняются быстро.

Разделение на очереди

app.conf.task_routes = {
    'app.tasks.send_password_reset': {'queue': 'high'},
    'app.tasks.send_notification': {'queue': 'default'},
    'app.tasks.generate_monthly_report': {'queue': 'low'},
}

Отдельные исполнители

celery -A config worker -Q high -c 4 -l info
celery -A config worker -Q default -c 4 -l info
celery -A config worker -Q low -c 2 -l info

Так тяжёлые фоновые задачи не смогут занять исполнителей, выделенных для срочных операций.

Приоритеты RabbitMQ

RabbitMQ поддерживает приоритет сообщений, если очередь создана с параметром x-max-priority. В Celery задачу можно отправить с числовым приоритетом.

send_notification.apply_async(
    args=[user_id],
    queue='notifications',
    priority=9,
)

Чем выше числовое значение, тем выше приоритет в пределах настроенной очереди. Однако приоритет не должен заменять отдельные очереди и ограничение ресурсов: бесконечный поток срочных задач может полностью вытеснить обычные.

Redis и приоритеты

Redis не даёт такую же нативную модель приоритетных очередей, как RabbitMQ. В Celery с Redis приоритет обычно приближённо реализуют несколькими физическими очередями. Поэтому для предсказуемости полезнее явно разделять задачи на high, default и low и запускать для них отдельные исполнители.

Защита от голодания

Если высокая очередь постоянно заполнена, низкоприоритетные задачи могут никогда не выполниться. Нужно установить лимиты, отдельную минимальную долю исполнителей для обычных задач, сроки действия задач и наблюдение за возрастом сообщений в очередях.

Как ответить на собеседовании

Для приоритетов сначала разделяю задачи на отдельные очереди и запускаю независимых исполнителей для high, default и low. RabbitMQ поддерживает нативные приоритеты очередей, а в Redis модель обычно приближённая, поэтому явное разделение очередей надёжнее. Также контролирую голодание низкоприоритетных задач и возраст сообщений.

Оцени свой прогресс

Честно оцени своё понимание этого вопроса, чтобы мы могли построить твой учебный трек максимально эффективно.
Читать в блоге