在cockroachdb中,为什么不确定度重启不更新不确定度窗口的上界?

问题描述 投票:1回答:1

我最近读到 这个 来自cockroachdb博客的一篇很棒的文章,其中谈到了他们如何以类似于扳手的方式保持一致性,但没有原子钟。以下是文章的相关部分。

当CockroachDB启动一个事务时,它选择了一个临时的提交时间戳 基于当前节点的墙时间。它还通过添加集群的最大时钟偏移量[提交时间戳,提交时间戳+最大时钟偏移量]来建立所选壁时间的上界。这个时间区间代表了不确定性的窗口。

...

只有当观察到一个值在不确定性区间内时,CockroachDB特有的机器才会启动。这里的核心问题是,鉴于时钟偏移,我们无法确定遇到的值是否在我们的事务开始之前就已经提交了。在这种情况下,我们只需通过执行不确定性重启,将临时提交的时间戳提升到所遇到的时间戳之上,就可以确定。最关键的是,不确定性区间的上界在重启时不会改变,所以不确定性窗口会缩小。从许多节点读取不断更新数据的事务可能会被迫多次重启,不过时间绝不会超过不确定性区间,每个节点也不会超过一次。

具体来说,我不明白为什么不确定度窗口的上界在不确定度重启过程中不也要被撞开。下面是一个例子来说明我的困惑。

想象一下,我们有两个写入A和B(在不同的节点上)。写A的时间戳为3,B的时间戳为5。假设最大时钟偏移量为3个时间单位,如果我们在一个时钟当前读数为1的节点上启动一个事务,我们将构建一个[1,4]的不确定性窗口。当我们遇到写A时,我们将执行不确定性重启以包含它,并将不确定性窗口减少到(3,4)。当我们遇到写B时,我们将忽略它,因为它位于不确定窗口的上界之上。但是,由于我们的最大时钟偏移量是3个单位,而A &B的时间戳相差不到3个单位,所以B可能发生在A之前,但是我们的事务中包含了A而没有包含B,所以我们没有一致性。

先谢谢你指出我遗漏的地方!

restart consistency cockroachdb uncertainty
1个回答
0
投票

很好的问题。这是很微妙的,我将尝试解释一下是怎么回事。

首先让我们看看涉及的事务。我们有两个写事务,A(ts=3)和B(ts=5)。如果这两个事务所触及的键有任何重叠,那么它们就无法 "不按顺序 "提交,我们可以确定事务A发生在事务B之前,但如果没有重叠的键,那么除了时钟之外,没有任何一个协调点可以保证这个顺序,而且由于时间戳距离很近,所以哪一个 "先发生 "是模棱两可的。

在这种模棱两可的情况下,我们想做的是指定某种顺序,认为交易是按照其时间戳所暗示的顺序发生的。这是很安全的,只要我们知道没有人 观察到 这是由CockroachDB内部管理读写交互的机制(主要是命名不当的 TimestampCache). 如果事务B后面有一个时间戳6的事务C,读取了A和B两个键,那么事务A就不允许再在时间戳3提交(会被推到时间戳7)。

只要数据库能够看到读和写之间的关系,就可以这样做。有时也会出现我们看不到的情况,如果写B对A有一些带外的因果依赖,但从来没有一个事务触及这两个键。这就是我们所说的 "因果逆向 "的异常情况,也是CockroachDB的可序列化隔离和Spanner的可线性化(或严格序列化)隔离级别的区别。

更新不确定性区间的上界将是避免因果反向异常的一种方法,尽管它将有严重的实际缺点--你可能不得不不断地重启,直到你发现在你的事务触及的所有键上的写入之间至少有一个你的最大时钟偏移量的差距。这可能永远不会成功。

© www.soinside.com 2019 - 2024. All rights reserved.