Утечка памяти Python Django Celery AsyncResult

Проблема заключается в очень серьезной утечке памяти до тех пор, пока сервер не выйдет из строя (или вы можете восстановиться, уничтожив рабочую службу 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

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
1 073
1

Ответы 1

Мы также столкнулись с множеством проблем с сельдереем в продакшене, а также решили проблему с утечкой памяти. Я не уверен, что объем нашей проблемы такой же, но если вы не возражаете, вы можете попробовать наше решение.

Видите ли, у нас было несколько задач, запущенных на паре воркеров, управляемых супервизором (все воркеры были в одной очереди). Теперь мы увидели, что когда в очереди стояло много задач, брокер (в нашем случае rabbitmq) отправлял количество задач, которые наши рабочие celery могли обработать, а остальные сохранял в памяти. Это привело к переполнению нашей памяти, и брокер начал разбиение на страницы на нашем жестком диске. Из документации мы узнали, что если мы позволим нашему брокеру не ждать результатов работы, эта проблема может быть решена. Таким образом, в наших задачах мы использовали вариант,

@task(time_limit=10, ignore_result=True)
def ggwp():
    # do sth

Здесь ограничение по времени закроет задачу через определенное время, а опция ignore_result позволит брокеру просто отправить задачу в celery workers, как только worker освободится.

Спасибо за объяснение вашего фона с этим, но, похоже, это другая проблема. Я игнорирую как результаты, так и ограничение по времени, это сломало какой-то бизнес, который зависит от результатов (что нормально), но память ВСЕ ЕЩЕ утекает с той же скоростью. Я заметил, что вы используете задачу вместо shared_task, почему?

MKX 26.02.2019 15:16

Другие вопросы по теме