我最近从 cockroachdb 博客中读到了这篇很棒的文章,其中讨论了它们如何以类似于扳手但没有原子钟的方式保持一致性。这是帖子的相关部分:
CockroachDB 启动事务时,它会根据当前节点的挂墙时间选择一个临时提交时间戳。它还通过添加集群的最大时钟偏移[提交时间戳,提交时间戳+最大时钟偏移]来建立所选挂钟时间的上限。该时间间隔代表不确定性窗口。
...
只有当观察到一个值在不确定区间内时,CockroachDB 特定的机制才会启动。这里的核心问题是,鉴于时钟偏移,我们无法确定遇到的值是否在我们的事务开始之前提交。在这种情况下,我们只需执行不确定性重启,将临时提交时间戳刚好高于遇到的时间戳即可。至关重要的是,不确定性区间的上限在重启时不会改变,因此不确定性窗口会缩小。从许多节点读取不断更新的数据的事务可能会被迫多次重启,但永远不会超过不确定间隔,每个节点也不会超过一次。
具体来说,我不明白为什么不确定性窗口的上限在不确定性重新启动期间也不必被碰撞。这是一个例子来说明我的困惑:
假设我们有两个写入 A 和 B(在不同的节点上)。写入 A 的时间戳为 3,B 的时间戳为 5。假设最大时钟偏移量为 3 个时间单位,如果我们在时钟当前读取为 1 的节点上启动事务,我们将构建 [1, 4] 的不确定性窗口。当我们遇到 write A 时,我们将执行不确定性重新启动以包含它并将不确定性窗口减小到 (3, 4]。当我们遇到 write B 时,我们将忽略它,因为它位于不确定性窗口的上限之上。但是,由于我们的最大时钟偏移量是 3 个单位,并且 A 和 B 的时间戳相距不到三个单位,B 可能发生在 A 之前。但是我们在事务中包含了 A 而不是 B,所以我们没有一致性。
提前感谢您指出我所缺少的!