【问题标题】:Google App Engine Saves and Avoiding Fetching Stale DataGoogle App Engine 保存并避免获取过时数据
【发布时间】:2014-10-29 19:48:40
【问题描述】:

我已经使用 App Engine 几年了,而 HDR 似乎一次又一次出现的一个问题是,当您在一个屏幕上更新数据时,有时会在读取时检索旧数据-如果只读请求是在更新后的一两秒内发出的,则该屏幕的唯一版本。我知道这已经被讨论过herehere。我知道问题是什么,但我想知道正确的解决方案可能是什么?这是一个我可以在哪里拥有陈旧数据的示例。

假设您构建了一个购物清单应用。

Entity 1: ShoppingList
Entity 2: ShoppingListItem

ShoppingList 实体上有一个字段,用于保存列表中项目的总金额。第二个实体是您的 ShoppingListItem。添加或删除 ShoppingListItem 时,需要更新 ShoppingList 上的总数。您有两种方法可以更新总数。

  1. 查询数据库并统计 ShoppingListItem 表中的商品数量。
  2. 在不计算数据库的情况下自动增加缓存的总计字段 +/- 1。

使用这两种解决方案,您最终都会得到陈旧的数据。 #1 可能已过时,因为添加/删除的原始保存可能尚未传播。因此查询将错过新记录。当您快速连续添加或删除多个项目时,#2 将具有陈旧的数据。保存 1 的总数已更新,但保存 2 时,保存 1 可能仍在传播,并且对保存 2 的 ShoppingList 总数的查询仍将反映保存 1 之前的原始状态。

所以我的问题是,解决此问题的正确方法是什么?在我看来,您有两个选择:

  1. 在使用缓存总计时,始终使用 memcached 实体。保存不会清除内存缓存,而是将更新后的实体直接注入回其中。这使 memcache 保持最新。这当然意味着未命中 memcache 的查询(例如获取所有 ShoppingList 实体的列表)可能仍会返回陈旧数据。但至少当所有的保存都完成时,数据库中缓存的总数是正确的。
  2. 处理这样一个事实,即您将拥有过时的数据,然后想办法在未来的某个时候清理它。要么安排一个 TaskQueue 重新查询 ShoppingList 并在 10-30 秒内更新总数,要么安排一个每 30 秒运行一次的 Cron 作业并查找所有已更新的 ShoppingList 实体。

我倾向于解决方案 #1。想法?

【问题讨论】:

    标签: google-app-engine


    【解决方案1】:

    选项 3 是仔细阅读 https://developers.google.com/appengine/docs/java/datastore/structuring_for_strong_consistencyhttps://developers.google.com/appengine/docs/java/datastore/structuring_for_strong_consistency。您遇到的是“最终一致性”的经典表现。特别注意实体组和祖先查询。

    【讨论】:

    • 感谢您的建议。不幸的是,由于每秒 1 的写入限制,我无法使用实体组。来自文档:“这种方法通过向每个留言簿写入单个实体组来实现强一致性,但它还将对留言簿的更改限制为每秒不超过 1 次写入(实体组支持的限制)”
    【解决方案2】:

    我认为在大多数情况下@david-w-smith 的回答是正确的。但是,我在对他的回答的评论中提到,使用实体组有很大的限制。该限制是实体组每秒只能处理一次写入。这对于只有少数用户的应用程序来说可能很好,但对于社交网络来说就不能接受了。

    正如 Google 文档 (https://developers.google.com/appengine/docs/java/datastore/structuring_for_strong_consistency) 所建议的那样,我使用 memcache 实现了一个相当极端的缓存实现。所有 shoppingList 查询结果都存储在缓存中,当列表被更新、添加或删除时,我也会更新缓存中查询结果的状态。我担心维护两个数据副本(数据库和内存缓存)的自然复杂性,但这就是 UnitTests 的用途。对吧?

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 2012-10-08
      • 2014-12-10
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 2015-10-07
      相关资源
      最近更新 更多