游标是否处理最终一致性?

时间:2013-12-06 17:17:03

标签: google-app-engine cursor google-cloud-datastore eventual-consistency

在App Engine文档中,我发现an interesting strategy使用游标跟踪数据存储中的更改:

  

游标的一个有趣应用是监视实体的看不见的变化。如果应用程序在每次实体更改时使用当前日期和时间设置时间戳属性,则应用程序可以使用按时间戳属性(按升序排序)的查询,并使用数据存储区光标检查实体何时移动到结果列表的末尾。如果更新了实体的时间戳,则使用游标的查询将返回更新的实体。如果自上次执行查询后没有更新实体,则不返回任何结果,并且光标不会移动。

但是,我不太确定这是如何一直有效的。毕竟,在使用高复制数据存储区时,查询最终只是一致的。因此,如果放置两个实体,并且查询只能看到两个实体中的后一个实体,则会将光标移动到两者之后。这意味着两个新实体中的第一个将保持看不见。

这是一个实际问题吗?或者游标是否还有其他方法可以解决这个问题?

2 个答案:

答案 0 :(得分:3)

在包含单调递增值(例如当前时间戳)的属性上具有索引(内置或复合)可能无法在高写入速率下执行。这种类型的工作负载将生成热点,因为索引的尾部不断更新,而不是在整个排序索引中分布的负载。但是,对于低写入率,这将正常工作。

答案的其余部分将取决于您是在同一实体组还是单独的实体组。

如果您的查询是祖先查询,因此在同一实体组中它可以非常一致(默认情况下是这样),并且所描述的方法应始终准确。查询将立即看到任何写入(对实体组内实体的更改)。

如果要查询多个实体组,这些实体组始终是一致的,则无法保证写入的应用/可见顺序。例如: - Time1 - 写EntityA - Time2 - 写EntityB - Time3 - 查询仅查看EntityB - Time4 - Query查看EntityA和EntityB

因此,使用游标检测更改的方法是正确的,但它可能会“跳过”某些更改。

有关最终/强一致性的更多信息,请参阅Balancing Strong and Eventual consistency with Google Cloud Datastore

答案 1 :(得分:1)

如果你能问一个曾经做过这件事的人,你可能会得到最好的通知,但在考虑了一下并重新阅读Paxos之后,我认为这应该不是问题,尽管这取决于如何数据存储区实际已实现。

游标本质上是索引中的一个位置。从理论上讲,您可以反复重复读取相同的光标,并看到新实体开始出现在它之后。在现实世界中,您通常会移动到最新的光标位置并忘记旧的光标位置。

出现最终一致性“问题”,因为索引的多个副本分布在多台计算机上。根据您从哪个索引读取,您可能会得到陈旧的结果。

您描述的问题是索引I有两个(确切)副本,并且创建了两个新实体,E1和E2。假设I1 = I + E1和I2 = I + E2,因此根据您读取的索引,您可能会获得E1或E2作为新实体,移动光标,并在索引被“修补”时丢失实体其他索引,即I2最终被修补到I + E1 + E2。

如果数据存储实际上是这样发生的,那么我怀疑,是的,你可能会遇到问题。但是,这种方式听起来很难,我怀疑数据存储区索引只有在Paxos投票达成协议后才会更新。所以你永远不会看到无序索引,你只会看到实体迟到:即你永远不会看到I + E2,你只会看到(I)或(I + E1)或(I + E1 + E2)

我怀疑,你可能会遇到一个问题,你可能会有一个对于尚未赶上的索引来说太新的游标。