【问题标题】:Google App Engine Datastore: Dealing with eventual consistencyGoogle App Engine Datastore:处理最终一致性
【发布时间】:2014-12-24 08:27:39
【问题描述】:

我正在开发一个 GAE Web 应用程序,我需要在没有祖先关系的两个实体的实例之间创建和删除关联(还要考虑同一个实例可能有多个关联,这些关联可能在创建祖先关系后随时间变化) ,无法删除)。 我经历过“最终一致性”政策,这意味着我的网页中的数据不会与我正在创建/删除的关系连贯地刷新。 但是我已经看到,通过两次执行 put() 方法,一致性似乎是强制的。

这符合“最终一致性”定义,该定义指出“......如果没有进行新的更新......”数据最终将保持一致,因为我正在进行另一次更新(实际上两次相同)我猜系统会强制保持一致性。

我说的对吗?还有其他更优雅的方法吗?

更新:我的目标

假设我有一个 A 类型实体的列表,它们实际代表什么并不重要,假设它们代表我业务的主要实体 我有一个 B 类型的另一个实体的列表,表示 A 类型的实体可以依赖的服务。 这是一个多对多的关系,所以 A 服务 b 可以被许多 A 类型的实体 a 使用 一个实体 a 可以由许多 B 类型的服务 b 服务

我有一个网页允许我创建这种关系(一个 Jinja2 模板,带有来自客户端的 Jquery Ajax 回调和一个依赖于服务器端数据存储的 webapp2 python 请求处理程序)。 当从数据存储中删除关系时,我通过对 a 实体进行另一个查询并描述它与之相关的 b 键列表来刷新数据。在这种情况下,我仍然在与 a 相关的 b 键列表中看到已删除的 b.key。这不是我所期望的。

更新:一些代码

这是模型

class A(ndb.Model):
    name = ndb.StringProperty()
    services = ndb.KeyProperty(repeated=True)

class B(ndb.Model):
    name = ndb.StringProperty()
    servedEntities = ndb.KeyProperty(repeated=True)

这是我用来创建关系的代码

                a.services.append(b.key);
                b.servedEntities.append(a.key);
                a.put()
                b.put()

这是我用来删除关系的代码

               a.services.remove(b.key);
               b.servedEntities.remove(a.key);
               a.put()
               b.put()

a和b之间没有祖先关系(也不可能存在) 删除关系后,如果再次从数据存储中检索 a,我仍然可以看到 b.key 在 a.services 中列出

【问题讨论】:

  • 你不能通过两次 put 来强制它,它没用。您能描述一下为什么需要它们保持一致吗?
  • 更新了,希望我已经清楚了
  • 如果您将尽可能少地包含代表问题的代码示例 - 会更容易为您提供帮助。
  • 更新了一些代码
  • 只有在查询时才可见,对吧?如果你会尝试a.key.get() -- b 在那里列出?

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


【解决方案1】:

您的问题的答案在于以下陈述:

当从数据存储中删除关系时,我会刷新数据 通过对实体进行另一个查询。

为什么需要新查询?

假设用户订阅了服务 x、y 和 z。现在用户告诉您从列表中删除服务 z。您转到数据存储并进行必要的更改。但是,您无需运行新查询(可能仍会在返回的实体中显示 z),您只需从客户端的用户实体中删除 z 并相应地更新 UI。

这显然是一个简化的例子。我在编写学校安排应用程序时遇到了类似的挑战,该应用程序有一个更复杂的用例 - 单个更改可能会影响所选时间段内的许多实体(例如“在每个上学日安排一堂课,直到季度末”) ,所以我很想简单地运行一个新查询来刷新计划视图。显然,我遇到了最终的一致性问题,因为有时必须创建数十个实体,这一问题被放大了。然后我意识到我已经拥有了刷新视图所需的所有数据,而无需运行新查询。代码有点多,但它是一个干净可靠的解决方案。

【讨论】:

  • 好的,但是如果用户刷新页面,他会看到旧项目又回来了
  • 考虑到用户手指的速度和网络延迟,刷新的页面将被正确更新,除非用户以某种方式设法在点击保存按钮后的几毫秒内点击刷新按钮。这种情况多久发生一次?你想把你的写入成本加倍来解决这种可能性吗? (根据我的经验,即使涉及多个实体,最终一致性也很少需要超过一秒钟的时间自行解决)。
  • @lowcoupling 因为这是一个 ajax-y 应用程序,所以刷新不太常见。您还可以 [利用 memcache][1] 来尽量减少这种情况的发生。但是,最后,如果您需要这种一致性,您的选择是 1) 重组架构以使用实体组或数据存储区的其他高度一致的功能,或者 2) 不使用应用程序引擎。 cloud.google.com/datastore/docs/articles/…
猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多