我的场景如下:我有一个大型机器学习模型,由一群工人计算。实质上,工人计算自己的模型部分,然后与结果交换,以维持全局一致的模型状态。
因此,每个芹菜任务都会计算它自己的工作。
但这意味着,任务都没有无状态,这就是我的麻烦:如果我说some_task.delay( 123, 456 )
,实际上我 NOT 在这里发送两个整数!
我发送完整的任务状态,在Celery的某处腌制。这种状态通常约为200 MB: - ((
我知道,在Celery中选择合适的序列化程序是可能的,但我的问题是不如何挑选任何可能在任务中的数据。 如何挑选任务的参数? 这是来自celery / app / task.py的引用:
def __reduce__(self):
# - tasks are pickled into the name of the task only, and the reciever
# - simply grabs it from the local registry.
# - in later versions the module of the task is also included,
# - and the receiving side tries to import that module so that
# - it will work even if the task has not been registered.
mod = type(self).__module__
mod = mod if mod and mod in sys.modules else None
return (_unpickle_task_v2, (self.name, mod), None)
我根本不希望这种情况发生。 有没有一个简单的方法,或者我只是被迫建立自己的芹菜(这是难以想象的)?
答案 0 :(得分:1)
不要使用芹菜结果后端。使用单独的数据存储。
虽然您可以使用Task.ignore_result
,但这意味着您无法跟踪任务状态等。
最佳解决方案是使用一个存储引擎(例如Redis)作为结果后端。 您应该设置一个单独的存储引擎(一个单独的Redis实例,或者像MongoDB一样,根据您的需要)来存储实际数据。
通过这种方式,您仍然可以看到任务的状态,但是大数据集不会影响芹菜的操作。
切换到JSON
序列化程序可能会减少序列化开销,具体取决于您生成的数据的格式。但是,它无法解决在结果后端输入过多数据的根本问题。
结果后端可以处理相对少量的数据 - 一旦超过某个限制,就会开始阻止其主要任务的正常运行 - 任务状态的通信。
我建议更新您的任务,以便他们返回包含有用元数据的轻量级数据结构(以促进任务之间的协调),并将“真实”数据存储在专用存储解决方案中。
答案 1 :(得分:0)
您必须按照文档中的说明定义任务中的忽略结果:
任务。的 ignore_result 强>
不存储任务状态。请注意,这意味着您无法使用AsyncResult检查任务是否已准备就绪,或获取其返回值。
答案 2 :(得分:-1)
那有点不受欢迎,但仍然。
我理解的是这里发生的事情。您有几个进程,它们与进程间通信并行执行大量计算。所以,不要不满意芹菜,你可以:
虽然不需要编写自己的芹菜,但需要编写一些代码。