使用谷歌应用引擎的线程型解决方案

时间:2012-03-20 21:53:33

标签: python multithreading google-app-engine transactions bigtable

我在谷歌应用引擎上有一个大约一百万个实体的“队列”。我必须使用查询从队列中“弹出”项目。

有很多客户端进程在不断向堆栈发出请求的地方运行。我的问题是,当其中一个客户端请求一个项目时,我想确保我从队列的前面删除该项目,将其发送到该客户端进程,而不是其他进程。

目前,我正在查询该项目,修改其属性,以便对队列的查询不再包含该项目,然后保存该项目。使用此方法,将一个项目同时发送到多个客户端进程是很常见的。我怀疑这是因为我在进行写入时以及当它们被反映到其他进程时会有延迟。

也许我需要以某种方式使用交易,但当我调查时,有一些“陷阱”。解决这个问题的好方法是什么?

2 个答案:

答案 0 :(得分:2)

有没有理由不使用App Engine的TaskQueue API来实现“队列”?如果队列的大小是问题,TaskQueue可能包含付费应用程序的up to 200 million Tasks,因此可以轻松处理一百万个实体。

如果您希望能够模拟队列中某个任务的查询,可以使用task tags,让您的客户端进程拉出任务,并处理某个标记。请注意,pull queues支持拉取任务,而不是push queues

除此之外,如果要保留“队列实体”实现,可以使用Memcache API向客户端进程发送需要处理的实体的信号。当您需要在应用程序实例之间共享数据与HRD数据存储的最终一致性时,Memcache提供更强的一致性,但需要注意的是Memcache中的数据可能会在任何时间点丢失。

答案 1 :(得分:1)

我认为有两种方法可以解决这个问题:

  1. 你正在做的事情还可以,你只需要使用交易。如果您的流程超过30秒,那么您可以将它们卸载到任务队列,这可以是交易的一部分。

  2. 您可以使用Pull Queues填充队列,而不是客户端进程以原子方式从队列中提取任务(租约删除周期)。使用Pull Queues,您可以确保任务仅租用一次。此外,任务必须在完成后从队列中手动删除,这意味着如果您的进程死亡,任务将在租约到期后重新排入队列。