2015-04-29 89 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,但代碼已經以這種方式編寫,我無法一次做出這麼大的改變 –