2015-04-29 88 views
0

我的场景如下:我有一个大型机器学习模型,它由一群工人计算。实质上,工人计算他们自己的模型部分,然后与结果进行交换,以保持全局一致的模型状态。如何避免酸洗芹菜任务?

因此,每个芹菜任务计算它是自己的一份工作。 但是这意味着,任务不是无状态的,这里是我的麻烦:如果我说some_task.delay(123, 456),实际上我是不是在这里发送两个整数!

我发送整个任务的状态,这是在芹菜某处腌制的。这种状态通常是约200 MB: - ((

我知道,这是可能的选择芹菜像样的串行器,但我的问题是如何咸菜只是任何数据,这可能是在任务 。 ?如何咸菜任务的参数只有 这里是芹菜/应用/ 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

你必须定义忽略从你的任务结果,因为它在文档中说:

任务。 ignore_result

不存储任务状态。请注意,这意味着您不能使用AsyncResult检查任务是否就绪,或者获取其返回值。

+0

谢谢,里卡多,但实际上需要使用AsyncResult。这是整个方案的关键点。也许可以将任务状态分成假的“可存储”部分(只是为了使AsyncResult工作)和任务的“可用”状态,而不是每个请求的腌制状态?我的请求量非常高,每个请求移动200Mbs是不可能的。 –

1

不要为此使用芹菜结果后端。使用单独的数据存储。

虽然你可以只使用Task.ignore_result这将意味着你失去跟踪任务的能力状态等

最好的解决办法是使用一个存储引擎(例如Redis的),你的结果后端。 您应该设置一个单独的存储引擎(根据您的需要设置Redis的一个单独实例,或者像MongoDB之类的东西)来存储实际数据。

通过这种方式,您仍然可以看到您的任务状态,但大数据集不影响芹菜的操作。

根据您生成的数据格式,切换到JSON序列化器可能会减少序列化开销。但是它无法解决通过结果后端放置太多数据的根本问题。

结果后端可以处理相对较少量的数据 - 一旦您超过了某个限制,就会开始阻止其主要任务的正确操作 - 任务状态的通信。

我建议更新您的任务,以便它们返回包含有用元数据的轻量级数据结构(例如,促进任务之间的协调),并将“真实”数据存储在专用存储解决方案中。

+0

谢谢,scytale,但我已经在我的代码中有以下定义:app = Celery('tasks',backend ='redis://54.221.232.248',broker ='redis://54.221.232.248')。但无论如何,任务状态仍然是酸洗:-(我真的很困惑 –

+0

简化了一些:'broker'用于发送消息(包含参数)到任务,'backend'用于返回任务的结果。在你的情况下,你使用的是同一个redis实例,这会导致邮件调度被大量结果超载。我建议a)使用rabbitmq代理,redis作为后端b)不要从你的代码中返回大数据集任务。而是将它们存储在第三方数据存储中(也许是单独的redis实例)并仅返回任务中的元数据 – scytale

+0

再次感谢@scytale,但我不想将结果存储在包括Redis在内的任何外部源中,因为这样做会无论如何意味着网络压力。将任务的本地数据存储在进程内存中并将仅更新模型状态作为普通Python数组发送(每N次请求一次),但是如何禁用酸洗并在外部存储中存储状态是可以的?进程内存对我来说很好 –

-1

这将是一个有点offtop,但仍然。

据我所知,这里正在发生。您有几个过程,与进程间通信并行执行大量计算。所以,相反的不满意你的情况,芹菜,你可以:

  • 使用zmq进程间通信(仅发送必要的数据),
  • 使用supervisor管理和运行的进程(numprocs尤其将有助于运行多个相同的工人)。

虽然它不需要编写自己的芹菜,但需要编写一些代码。

+0

谢谢@pavel_form,但代码已经以这种方式编写,我无法一次做出这么大的改变 –