1

我在谷歌應用引擎上有一百萬個實體的「隊列」。我必須通過使用查詢將隊列中的項目「彈出」。谷歌應用引擎的線程化解決方案

有很多客戶端進程在不斷向堆棧發出請求的地方運行。我的問題是,當其中一個客戶端請求某個項目時,我想確保將該項目從隊列的前面移除,並將其發送到該客戶端進程,而不是其他進程。

目前,我正在查詢該項目,修改其屬性,以便對該隊列的查詢不再包含該項目,然後保存該項目。使用這種方法,一個項目被同時發送到多個客戶端進程是非常普遍的。我懷疑這是因爲當我寫作時以及它們被反映到其他過程中時有延遲。

也許我需要以某種方式使用交易,但是當我研究這些時,出現了一些「陷阱」。解決這個問題的好方法是什麼?

+0

您的隊列是如何表示的?在應用程序引擎隊列中? – 2012-03-20 22:17:21

+0

我假設你正在實現數據存儲上的「隊列」?問題標題似乎與問題的主體無關,爲什麼GAE需要「線程式解決方案」? – 2012-03-20 22:46:20

回答

1

我看到兩種方法來解決這個:

  1. 你在做什麼是好的,你只需要使用事務。如果您的流程長於30秒,那麼您可以將它們卸載到任務隊列中,這可以是事務的一部分。

  2. 您可以使用Pull Queues填寫隊列,並且客戶端以原子方式(租約 - 刪除循環)從隊列中抽取任務。使用Pull Queues,您可以確保該任務僅租用一次。此外,任務必須在完成後從隊列中手動刪除,這意味着如果您的進程死亡任務將在租約到期後放回隊列中。

+0

我最終爲此使用了事務。這有點複雜,因爲我必須使用無法在事務內完成的查詢來確定隊列「前端」的實體。我使用了「僅鍵」查詢。然後在一個事務中,通過鍵將實體拉出來,修改它以將其發送到隊列的後面,然後保存它。 – 2012-04-04 15:14:40

2

是否有任何理由不使用App Engine的TaskQueue API來實現「隊列」?如果隊列的大小是問題,TaskQueue可能包含up to 200 million Tasks付費應用程序,因此可以輕鬆處理一百萬個實體。

如果您希望能夠模擬隊列中某個任務的查詢,那麼可以使用task tags,讓您的客戶端進程使用某個標記處理任務。請注意,通過pull queues而不是push queues支持拉取任務。

除此之外,如果你想保持你的「隊列 - 實體」實現,你可以使用Memcache API來通知客戶端進程需要處理哪個實體。當需要在應用程序實例之間共享數據時,Memcache提供了更強的一致性,與HRD數據存儲的最終一致性相比,Memcache中的數據在任何時間點都可能會丟失。

+0

注意,由於這裏沒有明確指出,所以Task Queue支持'pull'隊列,其中隊列項由進程獲取而不是自動執行。 – 2012-03-21 06:58:27

+0

@NickJohnson感謝您的補充,尼克!我已經更新了我的答案,使其更加明確,我所指的隊列是Pull Queues。 – 2012-03-23 06:42:06