2010-07-12 135 views
3

我正在使用Python GAE SDK。Google App Engine:如何使用任務隊列進行此處理?

我有一些處理需要在的6000多個實例上完成。在單個請求中執行速度太慢,所以我正在使用任務隊列。如果我只讓一個任務處理一個實體,那麼它只需要幾秒鐘。

documentation表示只能在「批次」中添加100個任務。 (這是什麼意思?在一個請求中?在一個任務中?)

所以,假設「批處理」的意思是「請求」,我試圖找出最好的方法是創建一個任務數據存儲中的每個實體。你怎麼看?

如果我可以假設MyKind的順序永遠不會改變,那麼會更容易。 (處理永遠不會改變MyKind實例 - 它只會創建其他類型的新實例。)我可以完成一大堆任務,給每個任務啓動一個偏移量,間隔小於100。然後,每個任務都可以創建執行實際處理的單個任務。

但是如果有太多的實體,原始請求無法添加所有必要的調度任務會怎麼樣?這讓我覺得我需要一個遞歸解決方案 - 每個任務都會查看它給出的範圍。如果在該範圍內僅存在一個元素,則對其進行處理。否則,它會將範圍細分爲後續任務。

如果我不能指望使用偏移和限制來識別實體(因爲它們的順序不能保證是恆定的),也許我可以使用它們的鍵?但隨後我可能會發送1000個左右的密鑰,這似乎很笨重。

我在這裏走正確的道路,還是應該考慮另一種設計?

+0

我面臨同樣的問題。看看我想要做什麼http://stackoverflow.com/questions/3211916/how-fast-google-app-engine-is 看到我的第二個答案。如果你找到任何解決方案,請告訴我。 – Manjoor 2010-07-13 13:54:38

回答

9

當您運行代碼taskqueue.add(url='/worker', params={'cursor': cursor})時,您正排隊執行任務;使用您提供的參數調度帶外執行請求。您可以在一次操作中安排多達100個。

雖然我不認爲你想。任務鏈將使這個簡單了很多:

你工作者的任務將做這樣的事情:

  • 運行查詢來處理獲取一些記錄。如果在任務參數中提供了遊標,請使用它。將查詢限制爲10條記錄,或者您認爲可以在30秒內完成的任何內容。

  • 處理您的10條

  • 如果您的查詢返回的10條記錄,排隊另一個任務,並從您的查詢傳遞更新的光標,它可以拿起你離開的地方。

  • 如果您的記錄少於10條,則表示完成。萬歲!發一封電子郵件或其他東西並退出。

有了這條路線,您只需啓動第一個任務,剩下的就自己添加了。

請注意,如果某個任務失敗,則App Engine將重試該任務直至成功爲止,因此您不必擔心數據存儲區打嗝導致一個任務超時並斷開連鎖。

編輯:

上述步驟不保證實體將只處理一次。任務通常只應運行一次,但Google建議您爲冪等性設計。如果它是一個主要關注點,這裏的處理的一種方式:

  • 放在每個實體的狀態標誌進行處理,或創建一個互補的實體持有的標誌。它應該有類似於待處理,處理和處理的狀態。

  • 當您獲取要處理的新實體時,事務鎖定並遞增處理標誌。只有在實體處於待處理狀態時才運行該實體。處理完成後,再次增加標誌。

請注意,在開始之前將處理標誌添加到每個實體並不是必須的。您的「掛起」狀態可能意味着該財產或相應的實體尚不存在。

+0

好吧,如果我這樣做,我可以確定所有記錄都會被處理一次,而不是更多? – 2010-07-12 05:21:09

+0

編輯爲考慮重複處理。 – 2010-07-12 12:58:07

0

也取決於你的設計,你可以做我做的,這是所有需要處理的記錄的編號。我處理了大約3500件物品,每件需要3秒左右的時間來處理。爲了避免重疊,超時並考慮到未來的擴展,我的第一個任務從數據庫中獲取所有這類獨特項目的列表。然後它將其分成500個每個項目標識符的列表,循環直到它佔據我數據庫中的所有唯一項目,並將每個500個標識符塊發佈到第二層處理程序任務。每個第二處理程序任務(當前是七個或八個不同的任務)都有一個唯一的500個項目列表,每個處理程序任務添加500個任務,每個唯一標識符一個。

因爲它都是通過循環和基於我的數據庫中唯一項目的數量進行計算的,所以我可以添加儘可能多的獨特項目,並且任務數量將擴大以適應它們,絕對不會有重複。我使用它在每天的遊戲中跟蹤價格,所以它都使用cron作業來解僱,並且根本不需要我的干預。

相關問題