【问题标题】:Python Django Celery AsyncResult Memory LeakPython Django Celery AsyncResult 内存泄漏
【发布时间】:2019-07-18 23:38:10
【问题描述】:

问题是一个非常严重的内存泄漏,直到服务器崩溃(或者您可以通过杀死 celery 工作者服务来恢复,这会释放所有使用的 RAM)

似乎有一堆关于这件事的错误报告,但很少有人注意这个警告,在 celery API 文档中,here

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

并且可以合理地假设泄漏与此警告有关。

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

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

在调用 get() 方法之前永远不要让 AsyncResult 对象超出范围的解决方案吗?

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

BROKER_URL = 'pyamqp://localhost' #rabbitMQ

【问题讨论】:

    标签: python django celery celery-task


    【解决方案1】:

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

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

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

    这里,时间限制将在一定时间后关闭任务,ignore_result 选项将允许代理在工作人员被释放后立即将任务发送到 celery 工作人员中。

    【讨论】:

    • 感谢您解释您的背景,但这似乎是一个不同的问题。我忽略了结果和时间限制,它破坏了一些依赖结果的业务(这很好),但内存仍然以完全相同的速度泄漏。我注意到您使用的是 task 而不是 shared_task,这是为什么呢?
    猜你喜欢
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 2012-12-02
    • 2011-12-13
    • 2014-02-26
    • 2010-11-27
    相关资源
    最近更新 更多