1

我已经使用 Google App Engine 几个月了,最近我开始怀疑我在 Datastore 方面的一些做法。我有大约 10 个实体,每个实体有 10-12 个属性。一切都在我的应用程序中运行良好,代码非常简单,我的数据结构方式非常简单,但我想知道我是否应该将这些大实体分解为更小的实体,以优化读写或遵循最佳实践(我不确定GAE)

现在我已经超过了我的读写配额,并希望控制这些配额。

4

3 回答 3

3

优化读取:

  • 如果您在查询中使用偏移量,则偏移量实体被计为读取。如果您运行偏移量 = 100 的查询,数据存储区将检索并丢弃前 100 个实体,并且您需要为这些读取付费。尽可能使用游标来减少读取操作。游标也会导致更快的查询。

  • 当您运行查询时,NDB 不一定会减少读取。对数据存储进行查询并返回实体,不发生内存缓存交互。如果要在查询上下文中从 memcache 中检索实体,则需要运行 keys_only 查询,然后尝试从 memcache 中检索这些键。然后,您需要转到数据存储区以查找任何缓存未命中的实体。检索密钥是一个“小”操作,是读取操作成本的 1/7。

优化写入:

  • 删除未使用的索引。默认情况下,实体上的每个属性都被索引,并且每个属性都会在第一次写入时产生 2 次写入,而在修改时会产生 4 次写入。您可以像这样禁用属性的索引:firstname = db.StringProperty(indexed=False)。

  • 如果您使用列表属性,则列表中的每个项目都是实体上的单个属性。列表属性是为方便而提供的抽象。一个名为 things 且值为 ["thing1", "thing2"] 的列表属性实际上是数据存储中的两个属性:things_0="thing1" 和 things_1="things"。与索引结合使用时,这可能会变得非常昂贵。

  • 合并您不需要查询的属性。如果您只需要查询一个或两个属性,请序列化其余属性并将其作为 blob 存储在实体上。

进一步阅读:

于 2013-03-01T17:27:06.127 回答
1

我建议考虑使用 NDB 实体。NDB 将在对数据存储执行读/写之前使用上下文缓存(如果需要,还可以使用 Memcache)。这应该可以帮助您保持在配额范围内。

在此处阅读有关 NDB 如何使用缓存的更多信息:https ://developers.google.com/appengine/docs/python/ndb/cache

有关 GAE 最佳实践的讨论,请参阅此页面:https ://developers.google.com/appengine/articles/scaling/overview

于 2012-12-10T18:58:44.277 回答
1

AppEngine Datastore 对每次读取的实体收取固定金额,无论实体有多大(尽管最大为 1MB)。这意味着将您经常阅读的多个实体组合成一个实体是有意义的。缺点只是延迟增加(因为它每次都需要反序列化一个更大的实体)。我发现这个延迟非常低(即使是大的也只有 1 位数的毫秒)。

在 Datastore 之上使用框架是一个好主意。我正在使用 Objectify,我很高兴。不过要小心使用 Memcache 集成。Googles 只为每个应用程序提供固定的有限内存量,因此一旦您谈论更大的数据,这将无法解决您的问题(因为实体已从 Memcache 中逐出,需要从数据存储区重新读取并放入缓存中每次读取再次)。

于 2012-12-10T19:08:38.153 回答