Как стать автором
Обновить

Комментарии 13

Сейчас будет критика. К переводчику замечаний почти нет кроме вопроса - зачем вы выбрали это невнятное бормотание двухлетней давности для перевода?

Во-первых, все примеры и "объяснения" в этой статье - только для Redis-брокера. Если использовать RabbitMQ - там нет никаких "unacked" очередей и работа сделана через родные AMQP-механизмы. Более того, сама celery ничего не знает про этих брокеров и использует еще несколько библиотек (того же автора) более низкого уровня для транспорта (kombu, amqplib), для работы с процессами (billiard), для сериализации и тп.

Брокеров тоже может быть довольно много разных и механизм работы с каждым движком тоже будет отличаться. Лучше всего использовать RabbitMQ, но проще всего Redis - поэтому он во всех примерах и идет.

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

Не очень понятно какие "неочевидные моменты" проясняет эта статья. На мой взгляд, только запутывает. Можно было бы рассказать о более насущных вещах: как правильно делать scheduled-таски, как масштабировать и отменять задачи, как запускать в продакшене, как делать мониторинг. И совсем уж актуальное - как организовать выполнение долгих тасков, отправляя их из асинхронного фреймворка типа FastAPI или даже из другого языка.

Да, действительно, возможно, это не самая лучшая статья для перевода. Но, честно, я не нашел чего-то более вразумительного. Возможно, плохо искал) Если поделитесь в комментах -- я только за ?

Большинство статей рассказывают, как просто поднять Celery в Django. Ну максимум еще скажут, что есть какой-то там брокер сообщений и система воркеров с очередями.

А лично для меня, не имеющего 10 лет опыта, эта статья ответила на некоторые вопросы.

напишите сами такую статью, было бы интересно почитать

Действительно, я бы с удовольствием посмотрел на пример production-ready Celery сервиса, который крутится в docker контейнере.

В Celery всё очень плохо с asyncio

Почему статья в хабе Django?

Ну не так уж и плохо. Если не использовать eventlet/greenlet, то можно взять eventloop и запустить асинхронные таски. Главное - дождаться их завершения. У меня довольно неплохо работает такой механизм для скачивания пачки файлов.

Вот с чем плохо - так это с потоками, насколько я помню. Не знаю уже как в последних версиях, но в (старой) версии 3 категорически нельзя было запускать потоки внутри таски. Если не починили ничего, то и всякие sync_to_async тоже могут не работать нормально.

eventlet/greenlet

Предлагаете дублировать код?

можно взять eventloop и запустить асинхронные таски

одну. асинхронную. таску. Э -- эффективность

Почему одну? Я имею в виду запустить одну celery-таску, в нем взять eventloop и запустить таски (не celery), дождаться завершения через asyncio.gather. Они работают асинхронно. celery-таска запускается все равно в отдельном процессе (prefork), eventloop ни с кем не шарится.

Я имею в виду запустить одну celery-таску, в нем взять eventloop и
запустить таски (не celery), дождаться завершения через asyncio.gather

То есть одна таска селери на воркер. Эффективность. Вы перечёркиваете все преимущества asyncio

Они работают асинхронно. celery-таска запускается все равно в отдельном процессе (prefork), eventloop ни с кем не шарится.

Именно. Все преимущества asyncio перечёркнуты

Есть обходной путь -- celery-pool-asyncio. Но это дикий костыль

Но.. В celery и так всегда одна таска на воркер! :) В классическом режиме, через prefork-пул, по крайней мере. Я не использую потоки, а eventlet - совершенно непредсказуемая штука и часто ломает остальные библиотеки (как было с openssl).

Если вы говорите про запуск celery-тасков через asyncio - да, этого нет и неизвестно будет ли вообще. Сначала, года 3 назад, обещали в версии 5, потом обещание переместилось в версию 6.

Однако, запускать asyncio внутри воркера вполне можно и нужно. У меня довольно крупные таски - например, скачать 50 гигабайтных файлов и объединить в один - прекрасно качаются все параллельно.

Но.. В celery и так всегда одна таска на воркер! :)

Аргументация в стиле:

-- Но позвольте, вы творите технический абсурд

-- Все так делают :)

У меня довольно крупные таски - например, скачать 50 гигабайтных
файлов и объединить в один - прекрасно качаются все параллельно.

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

Вообще говоря мы начали с вашего утверждения о том как все плохо с asyncio и я только уточнил что не все там плохо. Но если вы хотите научить меня как скачивать и склеивать файлы - я не против узнать ваши рекомендации.

Celery всегда был синхронным и всегда в воркере выполнялась ровно одна таска (если без eventlet/greenlet). В общем-то, основная задача таких обработчиков и была - взять все CPU-bound таски и выполнять где-то в бэкграунде. Asyncio совсем не поможет если вы запускаете обсчет матрицы или какую-нибудь ML-задачу.

я только уточнил что не все там плохо

Да, а фласк позволяет запускать event loop в каждой вьюхе. Значит ли это, что во фласке "не все там" плохо с асинхронностью? Да кому она нужна в таком виде?

Celery всегда был синхронным и всегда в воркере выполнялась ровно одна таска (если без eventlet/greenlet).

У вас чёрный пояс по взаимоисключающим параграфам. Оруэлл одобряет. Помимо перечисленных вами, селери поддерживает другие пулы, и кроме перечисленных я знаю ещё про threadpool-executor.

Я даже не знаю, как так можно в одном предложении опровергнуть себя же?

взять все CPU-bound таски

Отсебятина.

Asyncio совсем не поможет если вы запускаете обсчет матрицы или какую-нибудь ML-задачу

Ещё один интересный парадокс. Когда в собственном проде мы качаем/клеим файлы (IO), отправляем почту и вебхуки (IO) или процессим транзакции (IO), вы аппелируете к CPU-bound задаче. То есть как бы и да -- asyncio на CPU-bound бесполезен. Но и как бы и нет -- большинство задач IO-bound, включая ваш собственный пример

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации