Python Django Celery AsyncResult Утечка памяти - PullRequest
0 голосов
/ 25 февраля 2019

Проблема заключается в очень серьезной утечке памяти до тех пор, пока сервер не выйдет из строя (или вы не сможете восстановиться, убив службу работника сельдерея, которая освобождает всю используемую оперативную память)этот вопрос, но этому предупреждению уделяется очень мало внимания. В документации по сельдерею API здесь

Предупреждение: серверы используют ресурсы для хранения и передачи результатов.Чтобы обеспечить освобождение ресурсов, вы должны в конечном итоге вызвать get () или забыть () для КАЖДОГО Экземпляр AsyncResult, возвращаемый после вызова задачи.

И это разумнопредположить, что утечка связана с этим предупреждением.

Но концептуальная проблема, основанная на моем понимании сельдерея, заключается в том, что экземпляры AsyncResult создаются для нескольких представлений Django в пользовательском сеансе: некоторые создаются во время инициализации./ порождает новые задачи в одном представлении, а некоторые вы можете создать позже вручную (используя идентификатор_ задачи, сохраненный в сеансе пользователя) для проверки хода выполнения (состояния) этих задач в другом представлении.

Следовательно, объекты AsynResult будутв конечном итоге выходят за рамки нескольких представлений в реальном приложении Django, и вы не хотите вызывать get () в ЛЮБОМ из этих представлений, потому что не хотите замедлять процесс демона Django (или apache2).

Решение, позволяющее никогда не выпускать объекты AsyncResult из области видимости до вызова их get() метод?

CELERY_RESULT_BACKEND = 'django-db' #backend - это mysql DB

BROKER_URL = 'pyamqp: // localhost' # rabbitMQ

1 Ответ

0 голосов
/ 25 февраля 2019

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

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

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

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

...