【问题标题】:What is the most efficient way to use datastore in google appengine?在 google appengine 中使用数据存储的最有效方法是什么?
【发布时间】:2012-06-05 16:44:41
【问题描述】:

目前我正在做一个应该被很多人使用的项目。我担心数据存储区读/写/小型操作使用了太多资源。由于我是 appengine 的新手,是否有任何有效的方法可以使这些数字变小?我考虑过使用 memcache,但这不是最安全的方式。使用以下方法搜索数据存储实体也是一个好主意:

SELECT __key__ FROM table

然后使用:

....#code
table.get_by_id(entity.id())
....#code

?

非常感谢。

【问题讨论】:

  • table.get_by_id(entity.id()) 这部分没有意义。你已经拥有了实体,你又得到了它......
  • @aschmid00 让我们这么说吧。 results = db.GqlQuery("SELECT __key__ FROM chats") #some_code #let's say that I need some entity somebody = chats.get_by_id(results[0].id()) #... somebody.name = "whatever" somebody.put() 如果有更好的方法,如果你能告诉我,我会很高兴。
  • results[0] 是一个关键,那么为什么不db.get(results[0])?!我认为get_by_id 会重建一个关键对象以从数据存储中获取它......对此不确定,但我认为这样的往返太过分了。
  • @aschmid00 关于使用 db.get 是正确的。即使不是 100% 保留,您也应该使用 memcache。当缓存未命中时,您只需拉出记录并将其存储在缓存中。无论如何,您都会提取记录,为什么不使用 memcache 并保存一些数据存储读取。

标签: python google-app-engine datastore


【解决方案1】:

由于您使用的是 python,我强烈建议您使用新的数据存储 API,NDB

NDB 自动使用 memcache 在后台缓存它的模型,无需您做任何额外的工作。当然,您还应该考虑手动使用 memcache,ndb 不是灵丹妙药。但它会免费为您提供帮助,这总是很好。

除了性能提升之外,它还是应用引擎数据存储区的更简洁界面。它还完全支持bulk operations,这也可以提高性能。

【讨论】:

    【解决方案2】:

    对于经常读取和不经常写入的数据,使用数据存储前面的 memcache。读取时,首先检查数据是否在 memcache 中,如果没有,则从 datastore 中读取,然后将其存储在 memcache 中以供将来读取。在您通过键读取实体的简单情况下,您可以将每个实体按其数据存储键存储在内存缓存中。对于查询,您必须决定是否值得将结果集存储在 memcache 中,由查询参数键入。

    写入时,您可以删除 memcache 值,它会在下次读取时重新加载。您必须忍受删除失败的可能性。通常,您在 memcache 值上设置过期时间,以便旧值不会保留很长时间。请注意,对于每秒多次读取,即使是很短的到期时间也会让您获得显着的性能提升。

    您还可以以相同的方式将 memcache 用于其他耗时的数据操作,例如 URL Fetch 或计算值(例如复杂的模板化文本)。在所有这些情况下,如果 memcache 值已被逐出,您将回退到主要来源,因此您可以获得读取性能而不会失去对数据的访问权限。

    其他性能提示:尽可能使用批处理调用来减少 RPC 的数量。尽可能使用异步调用,这样您的应用在可能执行其他操作时不会阻塞服务调用。使用 AppStats 可视化您的服务调用并找到异步调用可能有帮助的领域。

    关于您的 fetch-by-key 问题:通常,执行仅键查询然后立即按键获取结果实体无济于事,因为这就是完整实体查询的全部内容。但是,如果您需要从查询结果中选择性地获取,或者如果在一个地方查询键并在另一个地方获取密钥是有意义的,那么这些都是可能的,并且您不会损失太多。我经常发现仅键查询的用途。另请参阅投影查询,仅获取(索引)属性的子集。

    【讨论】:

      【解决方案3】:

      在 Google App Engine 中使用 Datastore 最有效的方法是……不使用 Datastore!很慢。

      尽可能使用内存缓存。什么是内存缓存“不安全”?这当然是一个不同寻常的批评。

      此外,如果您知道实体的键或 ID,只需直接加载它,例如与get_by_key_name

      【讨论】:

      • 那我应该用什么? :) 我说 memcache 不安全的意思是因为命中率并不总是 100%,而且内存不会永远存在 :)。
      【解决方案4】:

      不,没有理由只进行键查询,然后单独获取实体,除非您只想检索由返回的键标识的一些实体。如果这样做更有效,数据存储将为您完成。只需进行常规查询即可。

      【讨论】:

        猜你喜欢
        • 2015-07-16
        • 2017-01-12
        • 2010-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-06
        • 2011-06-07
        相关资源
        最近更新 更多