在我的 Django 项目中,我有以下依赖项:

  • django==1.5.4
  • django-celery==3.1.9
  • amqp==1.4.3
  • kombu==3.0.14
  • librabbitmq==1.0.3(根据 https://stackoverflow.com/a/17541942/1452356 的建议)

  • 在 dev_settings.py 中:
    DEBUG = False
    BROKER_URL = "django://"
    import djcelery
    djcelery.setup_loader()
    CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
    CELERYD_CONCURRENCY = 2
    # CELERYD_TASK_TIME_LIMIT = 10
    
    CELERYD_TASK_TIME_LIMIT 按照此处的建议进行注释 https://stackoverflow.com/a/17561747/1452356 以及 https://stackoverflow.com/a/19931261/1452356 建议的 debug_toolbar
    我在 shell 中启动我的 worker :
    ./manage.py celeryd --settings=dev_settings
    

    然后我发送一个任务:
    class ExempleTask(Task):
    
      def run(self, piProjectId):
        table = []
        for i in range(50000000):
          table.append(1)
        return None
    

    使用 Django 命令:
    class Command(BaseCommand):
    
      def handle(self, *plArgs, **pdKwargs):
        loResult = ExempleTask.delay(1)
        loResult.get()
        return None
    

    和:
    ./manage.py purge_and_delete_test --settings=dev_settings
    

    我使用以下方法监控内存使用情况:
    watch -n 1 'ps ax  -o rss,user,command | sort -nr | grep celery |head -n 5'
    

    每次我调用任务时,它都会增加 celeryd/worker 进程的内存消耗,与其中分配的数据量成正比......

    这似乎是一个常见问题(参见其他 stackoverflow 链接),但是即使使用最新的依赖项,我也无法修复它。

    谢谢。

    最佳答案

    这是 Python 和 OS 问题,而不是真正的 django 或 celery 问题。不要太深入:

    1) 进程一旦从操作系统请求内存寻址空间,就永远不会释放它。它永远不会说“嘿,我在这里完成了,你可以把它拿回来”。在您给出的示例中,我预计流程规模会增长一段时间,然后稳定下来,可能会处于高基线。在您的示例分配之后,您可以调用 gc 接口(interface)来强制垃圾收集以查看如何

    2) 这通常不是问题,因为未使用的页面被操作系统调出,因为您的进程停止访问它已释放的地址空间。

    3)如果您的进程泄漏对象引用,阻止python进行垃圾收集以重新分配空间以供该进程稍后重用,并且要求您的进程从操作系统请求更多地址空间,那么这是一个问题。在某些时候,操作系统会喊叔叔并(可能)用它的 oomkiller 或类似机制杀死您的进程。

    4)如果您正在泄漏,请修复泄漏或设置 CELERYD_MAX_TASKS_PER_CHILD ,并且您的子进程(可能)会在扰乱操作系统之前自杀。

    这是关于 Python 内存管理的一个很好的一般性讨论:
    CPython memory allocation

    还有一些小事:
    使用 xrange 而不是 range - range 将生成所有值,然后遍历该列表。 xrange 只是一个生成器。是否设置了 Django DEBUG=False?

    关于Django Celery Memory 未释放,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22768559/

    10-11 22:22
    查看更多