获取,修改和放置一批具有ndb的实体的最有效方法

时间:2012-04-16 20:14:15

标签: google-app-engine google-cloud-datastore python-2.7 app-engine-ndb

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

我简化了我的模型来解释我的所作所为(无论如何这很简单):

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)

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

但是真正令我困扰的是,放置需要50秒......

在相当长的时间内完成此操作的最有效方法是什么。当然我知道这取决于很多因素,比如实体的复杂性,但是它需要的时间实际上超出了我的可接受限度。
我已经尝试过异步操作,tasklets ......

3 个答案:

答案 0 :(得分:8)

我想知道是否做了较小批量的例如50或100个实体会更快。如果将其转换为任务,则可以尝试同时运行这些tasklet。

我还建议使用Appstats查看此内容,看看是否显示出令人惊讶的内容。

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

答案 1 :(得分:0)

听起来像MapReduce的设计目的。您可以通过同时获取和修改所有实体来快速完成此操作,并跨多个服务器实例进行扩展。但是,通过使用更多实例,您的成本会上升。

答案 2 :(得分:0)

我会假设你有你想要的实体设计(也就是说我不会问你想要做什么,也许你应该有一个大实体而不是一堆小实体那些你必须一直更新的东西)。因为那不会很好。 (=

如果您使用了任务队列怎么办?您可以创建多个任务,每个任务可以将URL负责更新的密钥以及应该设置的属性和值作为URL参数。这样,工作被分解为可管理的块,用户的请求可以在后台工作时立即返回?那会有用吗?