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