Python Google应用程序引擎:如何使用任务队列进行此处理?

Python Google应用程序引擎:如何使用任务队列进行此处理?,python,google-app-engine,task-queue,Python,Google App Engine,Task Queue,我正在使用Python GAE SDK 我需要对6000多个MyKind实例进行一些处理。它太慢,无法在单个请求中完成,因此我使用任务队列。如果我让一个任务流程只有一个实体,那么它应该只需要几秒钟 报告称,一个“批次”只能添加100个任务。(这是什么意思?在一个请求中?在一个任务中?) 因此,假设“batch”表示“request”,我试图找出最好的方法是为数据存储中的每个实体创建一个任务。你觉得怎么样 如果我能假设MyKind的顺序永远不会改变,那就容易多了。(处理过程实际上永远不会改变MyK

我正在使用Python GAE SDK

我需要对6000多个
MyKind
实例进行一些处理。它太慢,无法在单个请求中完成,因此我使用任务队列。如果我让一个任务流程只有一个实体,那么它应该只需要几秒钟

报告称,一个“批次”只能添加100个任务。(这是什么意思?在一个请求中?在一个任务中?)

因此,假设“batch”表示“request”,我试图找出最好的方法是为数据存储中的每个实体创建一个任务。你觉得怎么样

如果我能假设
MyKind
的顺序永远不会改变,那就容易多了。(处理过程实际上永远不会改变
MyKind
实例——它只会创建其他类型的新实例。)我可以做一堆任务,给每个任务一个开始位置的偏移量,间隔不到100。然后,每个任务都可以创建执行实际处理的单个任务

但是,如果有太多的实体,原始请求无法添加所有必要的调度任务,该怎么办?这让我觉得我需要一个递归解决方案——每个任务都会查看给定的范围。如果范围中只存在一个元素,它将对其进行处理。否则,它会将范围进一步细分为后续任务

如果我不能指望使用偏移量和限制来识别实体(因为它们的顺序不能保证恒定),也许我可以使用它们的键?但我可能会发送1000把钥匙,这似乎很难处理


我在这里走的是正确的道路,还是我应该考虑另一个设计? 当您运行类似于
taskqueue.add(url='/worker',params={'cursor':cursor})的代码时,
您正在将任务排队;使用您提供的参数计划带外执行的请求。很明显,您可以在一次操作中安排多达100次

不过我觉得你不想。任务链接将使这一过程变得简单得多:

您的工作任务将执行以下操作:

  • 运行查询以获取一些记录以进行处理。如果任务参数中提供了游标,请使用它。将查询限制为10条记录,或任何您认为可以在30秒内完成的记录

  • 处理你的10条记录

  • 如果您的查询返回了10条记录,请将另一个任务排队,并将查询中更新的游标传递给它,以便它可以从您停止的地方继续执行

  • 如果你的记录少于10张,你就完了。好极了发一封电子邮件什么的然后退出

使用此路线,您只需开始第一个任务,其余任务将自行添加

请注意,如果任务失败,App Engine将重试该任务,直到它成功为止,因此您不必担心数据存储中断会导致一个任务超时并中断链

编辑:

上述步骤并不保证一个实体只被处理一次。任务通常只能运行一次,但Google建议您设计幂等性。如果这是一个主要问题,这里有一个解决方法:

  • 在要处理的每个实体上放置一个状态标志,或创建一个补充实体来保存该标志。它应该具有类似于挂起、处理和已处理的状态

  • 获取要处理的新实体时,事务性地锁定并递增处理标志。仅在实体处于挂起状态时运行该实体。处理完成后,再次增加该标志


请注意,在开始之前,严格来说没有必要向每个实体添加处理标志。您的“挂起”状态可能只是意味着属性或相应的实体还不存在。

也取决于您的设计,您可以执行我所做的操作,即为需要处理的所有记录编号。我处理大约3500个项目,每个项目需要3秒钟左右的时间来处理。为了避免重叠、超时并考虑将来的扩展,我的第一个任务从数据库中获取所有此类唯一项的列表。然后,它将其划分为每个项目标识符500个的列表,循环直到它解释了我数据库中的所有唯一项目,并将每个500个标识符块发布到第二层处理程序任务。第二个处理程序任务(当前为七个或八个不同的任务)中的每一个都有一个包含500个项目的唯一列表,并且这些处理程序任务中的每一个都添加了500个任务,每个任务对应一个唯一标识符


由于它都是通过循环进行管理的,并根据数据库中唯一项的数量进行计数,因此我可以添加任意数量的唯一项,并且任务的数量将扩展以适应它们,而绝对不会重复。我每天都用它来跟踪游戏中的价格,所以它完全是用cron作业来完成的,完全不需要我的干预

好的,如果我这样做,我可以确定所有的记录都将被处理一次,而不是更多?编辑以考虑重复处理。我面临着同样的问题。看看我想做什么,看看我的第二个答案。如果你有什么解决办法,请告诉我