【发布时间】:2015-08-10 18:59:39
【问题描述】:
我有一个导入成本很高的模块(它涉及下载一个 ~20MB 的索引文件),由 celery 工人使用。不幸的是,我不知道如何只导入一次模块,并且只能由 celery 工人导入。
版本 1 tasks.py 文件:
import expensive_module
@shared_task
def f():
expensive_module.do_stuff()
当我以这种方式组织文件时,Web 服务器和 celery 实例都导入了昂贵的模块,这是我所期望的,因为 tasks 模块在两者中都导入了,它们是不同的过程。
版本 2 tasks.py 文件:
@shared_task:
def f():
import expensive_module
expensive_module.do_stuff()
在这个版本中,Web 服务器从不导入模块(这很好),但是每次调用 f.delay() 时,celery 工作人员都会重新导入模块。这真的让我感到困惑。在这种情况下,为什么 celery worker 每次运行这个函数时都要重新导入模块?如何重新组织这段代码,让 celery 工人只导入昂贵的模块,并且只导入一次?
作为一个后续的、不太重要的问题,在 tasks.py 文件的版本 1 中,为什么 Web 实例两次导入昂贵的模块?当 django 运行 self._urlconf_module = import_module(self.urlconf_name) 时,两次都是从 urls.py 导入的。
【问题讨论】:
-
事情是 celery 任务是理想的幂等性,这意味着它们没有任何状态,并且在使用相同参数调用时总是提供相同的输出。 - 你有点引入状态,因此用芹菜做这件事可能会变得困难。
标签: python django celery django-celery