Проблема заключается в очень серьезной утечке памяти до тех пор, пока сервер не выйдет из строя (или вы можете восстановиться, уничтожив рабочую службу celery, которая освобождает всю используемую оперативную память)
Похоже, что по этому поводу есть множество сообщений об ошибках, но этому предупреждению уделяется очень мало внимания. В документах API сельдерея здесь
Предупреждение: Бэкенды используют ресурсы для хранения и передачи результатов. Чтобы убедиться, что ресурсы высвобождены, вы должен в конце концов вызываете get() или забыли() для экземпляра КАЖДЫЙ AsyncResult, возвращенного после вызова задачи.
И разумно предположить, что утечка связана с этим предупреждением.
Но концептуальная проблема, основанная на моем понимании сельдерея, заключается в том, что экземпляры AsyncResult создаются в нескольких представлениях Django в рамках пользовательского сеанса: некоторые создаются, когда вы инициируете/порождаете новые задачи в одном представлении, а некоторые вы можете создать позже вручную (используя task_id, сохраненный в сеансе пользователя), чтобы проверить ход выполнения (состояние) этих задач в другом представлении.
Следовательно, объекты AsynResult в конечном итоге выйдут за пределы области действия нескольких представлений в реальном приложении Django, и вы не хотите вызывать get() в ЛЮБОМ из этих представлений, потому что вы не хотите замедлять работу Django (или процесс демона apache2).
Является ли решение никогда не позволять объектам AsyncResult выходить за рамки до вызова их метода get()?
CELERY_RESULT_BACKEND = 'django-db' #backend - это БД mysql
BROKER_URL = 'pyamqp://localhost' #rabbitMQ






Мы также столкнулись с множеством проблем с сельдереем в продакшене, а также решили проблему с утечкой памяти. Я не уверен, что объем нашей проблемы такой же, но если вы не возражаете, вы можете попробовать наше решение.
Видите ли, у нас было несколько задач, запущенных на паре воркеров, управляемых супервизором (все воркеры были в одной очереди). Теперь мы увидели, что когда в очереди стояло много задач, брокер (в нашем случае rabbitmq) отправлял количество задач, которые наши рабочие celery могли обработать, а остальные сохранял в памяти. Это привело к переполнению нашей памяти, и брокер начал разбиение на страницы на нашем жестком диске. Из документации мы узнали, что если мы позволим нашему брокеру не ждать результатов работы, эта проблема может быть решена. Таким образом, в наших задачах мы использовали вариант,
@task(time_limit=10, ignore_result=True)
def ggwp():
# do sth
Здесь ограничение по времени закроет задачу через определенное время, а опция ignore_result позволит брокеру просто отправить задачу в celery workers, как только worker освободится.
Спасибо за объяснение вашего фона с этим, но, похоже, это другая проблема. Я игнорирую как результаты, так и ограничение по времени, это сломало какой-то бизнес, который зависит от результатов (что нормально), но память ВСЕ ЕЩЕ утекает с той же скоростью. Я заметил, что вы используете задачу вместо shared_task, почему?