在 Google App Engine 上的数据存储区中更新大量实体

Posted

技术标签:

【中文标题】在 Google App Engine 上的数据存储区中更新大量实体【英文标题】:Updating a large number of entities in a datastore on Google App Engine 【发布时间】:2012-06-27 13:04:18 【问题描述】:

我想对特定种类的所有实体执行一个小操作,并将它们重写到数据存储区。我目前有 20,000 个此类实体,但想要一个可以扩展到任意数量的解决方案。

我有哪些选择?

【问题讨论】:

【参考方案1】:

使用mapper - 这是 MapReduce 框架的一部分,但您只需要第一个组件 map,因为如果您只是改变数据存储实体,则不需要 shuffle/reduce 步骤。

【讨论】:

我实际上已经在使用 MapReduce 框架,因此流水线化这些操作似乎是个好主意。我担心的是有许多单 put() 操作并行运行。除了性能问题,我还担心数据存储超时,因为许多实体共享实体组。无论如何都要流水线并仍然聚合 put()s? map-reduce api 允许通过突变池进行批量数据存储操作。 code.google.com/p/appengine-mapreduce/wiki/…【参考方案2】:

Daniel 是正确的,但如果您不想弄乱映射器,这需要您向应用程序添加另一个库,您可以使用 Task Queues 或更简单地使用包含的 deferred library从 SDK 1.2.3 开始。

20.000 个实体并没有那么戏剧化,我认为这项任务不会定期执行(但即使执行,也是可行的)。

这是一个使用 NDB 和延迟库的示例(您可以使用 DB 轻松做到这一点,但如果您还没有使用它,请考虑切换到 NDB)。这是一种非常直接的方式,但不太关心超时:

def update_model(limit=1000):
  more_cursor = None
  more = True
  while more:
    model_dbs, more_cursor, more = Model.query().fetch_page(limit, start_cursor=more_cursor)
    for model_db in model_dbs:
      model_db.updated = True
    ndb.put_multi(model_dbs)
    logging.info('### %d entities were updated' % len(model_dbs))

class UpdateModelHandler(webapp2.RequestHandler):
  def get(self):
    deferred.defer(update_model, _queue='queue')
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write('The task has been started!')

【讨论】:

我对这种方法的主要担忧是达到实例内存限制,因为所有模型在写入之前都存储在内存中(我以前有过这些)。通过传递游标等,可以让 update_model 任务在给定数量的模型之后生成另一个 update_model 任务。 @TomerWeller 我不认为这是必要的,这不是一个侵入性测试,很容易将它应用到您自己的应用程序中......所以试一试,让我们知道 “在服务 1 个请求后,超过了 155.32 MB 的软专用内存限制”。我有 18,000 个实体,平均每个实体 10KB。这是预期的失败,因为基本前端实例有 128MB 的内存,而我正在尝试加载 180MB 的数据。很高兴 appengine 能让我达到 155 :) @TomerWeller 如果您转到应用程序设置,您可以将其增加到 512MB 内存。i.imgur.com/BZ4AN.png 这会将实体的数量限制为 51k。这种方法不允许水平缩放。

以上是关于在 Google App Engine 上的数据存储区中更新大量实体的主要内容,如果未能解决你的问题,请参考以下文章

在 Google App Engine 上的数据存储区中更新大量实体

在 Python 上的 Google App Engine 中按实体键名过滤

Google-App-Engine 上的 Grails - 它死了吗? [关闭]

Google App Engine 上的 JDO 与 JPA for Java

在 Google 虚拟机上处理来自 Google App Engine 的数据

如何从本地 Google App-engine 数据存储中删除所有实体?