【问题标题】:Threading-type solution with google app engine使用谷歌应用引擎的线程型解决方案
【发布时间】:2012-03-20 21:53:32
【问题描述】:

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

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

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

也许我需要以某种方式使用事务,但是当我研究它时,有几个“陷阱”。解决这个问题的好方法是什么?

【问题讨论】:

  • 您的队列是如何表示的?在应用引擎队列中?
  • 我假设您正在数据存储上实现“队列”?问题标题似乎与问题主体无关,为什么需要GAE的“线程类型解决方案”?

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


【解决方案1】:

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

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

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

【讨论】:

  • 请注意,由于这里没有明确指出,任务队列支持“拉”队列,其中队列项由进程获取而不是自动执行。
  • @NickJohnson 感谢您的附录,尼克!我已经更新了我的答案,以更明确地指出我所指的队列是 Pull Queues。
【解决方案2】:

我看到了两种解决方法:

  1. 你做的没问题,你只需要使用事务。如果您的进程超过 30 秒,那么您可以将它们卸载到任务队列,这可以是事务的一部分。

  2. 您可以使用Pull Queues,在其中填满一个队列,然后客户端进程以原子方式(租约-删除周期)从队列中拉出任务。使用拉取队列,您可以确保该任务只租用一次。此外,任务完成后必须手动从队列中删除,这意味着如果您的进程死亡任务将在租约到期后放回队列中。

【讨论】:

  • 我最终为此使用了事务。这有点复杂,因为我必须使用无法在事务中完成的查询来确定队列“前端”的实体。我使用了“仅限键”查询。然后在一个事务中,通过 key 拉出实体,修改它以将其发送到队列的后面,然后保存它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 2014-10-14
  • 2011-05-06
相关资源
最近更新 更多