Google app engine 使用ndb获取、修改和放置一批实体的最有效方法

Google app engine 使用ndb获取、修改和放置一批实体的最有效方法,google-app-engine,google-cloud-datastore,python-2.7,app-engine-ndb,Google App Engine,Google Cloud Datastore,Python 2.7,App Engine Ndb,在我的应用程序中,我执行了一些批处理操作。 不幸的是,更新400-500个实体有时需要很长时间。 我拥有的是所有的实体密钥,我需要获取它们,更新属性并将它们保存到数据存储中,保存它们可能需要40-50秒,这不是我想要的 我将简化我的模型来解释我所做的事情(无论如何,这很简单): 获取和修改不会花费太长时间。我试图让_async进入一个tasklet和任何其他可能的东西,只有在get或forloop花费更长时间时才会改变 但真正让我烦恼的是一次推杆需要50秒 在适当的时间内进行此操作的最有效方法是

在我的应用程序中,我执行了一些批处理操作。 不幸的是,更新400-500个实体有时需要很长时间。 我拥有的是所有的实体密钥,我需要获取它们,更新属性并将它们保存到数据存储中,保存它们可能需要40-50秒,这不是我想要的

我将简化我的模型来解释我所做的事情(无论如何,这很简单):

获取和修改不会花费太长时间。我试图让_async进入一个tasklet和任何其他可能的东西,只有在get或forloop花费更长时间时才会改变

但真正让我烦恼的是一次推杆需要50秒

在适当的时间内进行此操作的最有效方法是什么。当然,我知道这取决于许多因素,比如实体的复杂性,但所需的时间确实超出了我可以接受的限度。

我已经尝试过异步操作,Tasklet

听起来像是MapReduce的设计目标。通过同时获取和修改所有实体,跨多个服务器实例进行缩放,可以快速完成此任务。但是,使用更多实例会增加成本。

我将假设您拥有所需的实体设计(即,我不会问您正在尝试做什么,以及您应该如何拥有一个大实体,而不是一堆需要随时更新的小实体)。因为那样不太好。(=


如果您使用任务队列会怎么样?您可以创建多个任务,每个任务都可以将其负责更新的键以及应设置的属性和值作为URL参数。这样,工作就可以分解为可管理的块,并且当工作在后台进行时,用户的请求可以立即返回?这会不会rk?

我想知道,如果批量较小,例如50或100个实体,是否会更快。如果您将其放入任务中,则可以尝试同时运行这些Tasklet

我还建议大家用一个简单的例子来看看这是否显示了一些令人惊讶的事情


最后,假设这使用HRD,您可能会发现对每批实体组的数量有一个限制。该限制默认值非常低。请尝试提高它。

好,但这是一个按需操作。不确定mapreduce是否回答了我的问题。但当您说“按需”时,我可能错了,我假设您的意思是“HTTP请求已启动”。这并不能阻止您使用mapreduce。但是,在所有操作完成后检查结果会有点麻烦,但并非不可能。是的,它们是http请求初始化的。我需要检查操作/操作是否成功。您是否已经尝试过批处理获取/放置操作?否则,我不知道有比这更快的方法如果你在大数据上运行,需要时间来写,我会认真考虑异步写,并使用一个单独的HTTP请求来检查成功,以防你的原始连接超时。我想MapReduce API基本上是为你这样做的。您的工作,将其分为多个任务,然后并行发布任务,以便更快地完成。实体设计未经讨论,是的,我考虑设置任务,但我会遇到其他问题,如不知道操作是否失败,所有实体都在同一个实体组中并执行put分批处理可能会导致争用问题……我仍然无法理解一批处理是如何放入一堆实体的(我说的不是一百万个实体)可能需要花费将近一分钟的时间。这些不是后台任务,而是用户执行的操作,因此我需要知道操作是否立即失败或成功。GVR关于使用AppStats的提示可能对您有益。当您放置一个实体时,有多少索引被写入?有多少DB写入?可能有点过时,但是请看这篇文章,了解为什么放置一个实体可能需要一段时间:所有实体都在同一个实体组中,经过几次测试后,我不得不说,使用tasklet将实体放置在延迟任务批处理中50次,这会使此操作快得多。我说的是完整更新大约需要5-10秒,现在还没有完成我的想法是,但比50秒要好得多。我发现这很令人惊讶,如果它们都在同一个组中,那么不同的批不是会使您达到大约1次写入/秒/组的限制吗?我的意思是,我很惊讶,即使所有实体都在同一个组中,拆分成更多批也会有所帮助。他必须向h显示Appstats输出请帮我理解。可能他的实体很大。运行此脚本需要导入什么?
来自google.appengine.ext import ndb
class Entity(ndb.Model):
    title = ndb.StringProperty()

keys = [key1, key2, key3, key4, ..., key500]

entities = ndb.get_multi(keys)

for e in entities:  
    e.title = 'the new title'

ndb.put_multi(entities)