Python Django Celery AsyncResult内存泄漏

时间:2019-02-25 14:27:24

标签: python django celery celery-task

问题是非常严重的内存泄漏,直到服务器崩溃为止(或者您可以通过终止celery worker服务来恢复,该服务会释放所有使用的RAM)

在此问题上似乎已经报告了很多错误,但是对此警告的关注很少,在celery API文档中,here

警告: 后端使用资源来存储和传输结果。为确保释放资源,您必须最终在调用任务后返回的每个 AsyncResult实例上调用get()或忘记()。

并且有理由假设泄漏与该警告有关。

但是,根据我对celery的理解,概念上的问题是AsyncResult实例是在用户会话中的多个Django视图中创建的:有些是在您在一个视图中启动/生成新任务时创建的,有些可能是稍后创建手动(使用用户会话中保存的task_id)在另一个视图中检查这些任务的进度(状态)。

因此,AsynResult对象最终将超出现实世界中Django应用程序中多个视图的范围,并且您不想在任何这些视图中调用get(),因为您不想降低速度。 Django(或apache2)守护进程。

解决方案是在调用AsyncResult对象的get()方法之前绝不使其超出范围吗?

CELERY_RESULT_BACKEND ='django-db'#后端是一个mysql数据库

BROKER_URL ='pyamqp:// localhost'#rabbitMQ

1 个答案:

答案 0 :(得分:0)

我们在生产中还遇到了芹菜的多个问题,还解决了内存泄漏问题。我不确定我们的问题范围是否相同,但是如果您不介意,可以尝试我们的解决方案。

您看到我们在由主管管理的几个工作人员上运行了多个任务(所有工作人员都在同一队列中)。现在,我们看到,当有很多任务排队时,经纪人(在本例中为rabbitmq)正在发送芹菜工作者可以处理的任务数量,并将其余的任务保存在内存中。这导致我们的内存溢出,并且代理开始在我们的硬盘驱动器中分页。通过阅读文档我们发现,如果我们允许经纪人不等待工作人员结果,则可以解决此问题。因此,在我们的任务中,我们使用了选项,

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

在此,时间限制将在一定时间后关闭任务,而ignore_result选项将允许经纪人在工人释放后立即将其发送给芹菜工人。