等待和原子钟如何帮助GCP Spanner解决分布式事务中的线性化和串行化?

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

我对为什么分布式事务需要同步时钟的理解如下

假设 NTP 最大漂移为 250ms

true time = 100ms
node A local time = 100ms
node B local time = 0ms

以下交易将遇到顺序冲突

transactionA arrive nodeA at (true time 100ms, A time 100ms, B time 0ms)
transactionA commit by nodeA at (true time 110ms, A time 110ms, B time 10ms)
nodeB gets transactionA replicated at (true time 111ms, A time 111ms, B time 11ms) BUT with timestamp (110ms)
transactionB arrive nodeB at (true time 120ms, A time 120ms, B time 20ms)
transactionB is commit by nodeB at (true time 130ms, A time 130ms, B time 30ms)

现在transactionA和transactionB之间的交易时间有冲突

transactionA commit time = 110ms (local of A)
transactionB commit time = 30ms (local of B)

事务 A 应该在事务 B 之前处理,但是由于节点 B 落后节点 A 100ms,所以现在认为事务 B 在事务 A 之前处理

Spanner 有原子钟,保证最大时间漂移为 7ms,并且在提交之前等待 7ms 的最大不确定时间。但这如何从根本上解决问题呢?

想象下面的例子

true time = 7ms
node A local time = 7ms
node B local time = 0ms



trxA arrive nodeA at (true time 7ms, A time 7s, B time 0ms)
trxA commit by nodeA at (true time 8ms, A time 8ms, B time 1ms)
trxB arrive nodeB at (true time 9ms, A time 9ms, B time 2ms)
trxB is commit by nodeB at (true time 10ms, A time 10ms, B time 3ms)
nodeA report trxA after waiting 7ms (true time 15ms, A time 15ms, B time 8ms)
nodeB report trxB after waiting 7ms (true time 17ms, A time 17ms, B time 10ms)

在这个例子中,7ms等待并不能解决问题,trxB仍然在3ms(本地nodeB时间)提交,trxA在8ms(本地nodeA时间)提交

trxB在trxA之前提交的冲突仍然存在

我在这里缺少什么?

database concurrency distributed-system google-cloud-spanner
1个回答
0
投票

我在这里缺少什么?

这并不是 Spanner 时间戳分配的工作原理:您可以参考 https://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf,第 4.1.2 节了解更多细节)。看来您假设事务是使用本地节点时间时间戳提交的,而实际上时间戳选择为 TrueTime.Latest。

因此,在您的示例中,不匹配位于以下几行:

trxB 到达节点B(真实时间9ms,A时间9ms,B时间2ms) trxB为 由nodeB提交(真实时间10ms,A时间10ms,B时间3ms)

在这里,您似乎认为 trxB 提交时间戳将为 3ms,这小于 trxA 提交时间戳 8ms。 然而,如果你说真实时间是 9ms(实际上,并不清楚你的意思,因为真实时间不是由一个值表示,而是由两个值表示:最早和最新),当 txnB 到达 NodeB 时,提交时间戳为B 不能是 3ms,因为 Spanner 选择提交时间戳为 TrueTime.Later,不会小于 9ms。

因此,最好根据实时和真实时间值对重写您的示例:因此,在您的示例中,节点A和节点B之间的漂移是7毫秒,节点A时间是完美的(TrueTime.Earliest=TrueTime.Latest)。

  1. trxA 在 RealTime=7 时到达节点 A,TrueTime 在节点 A=[7,7] 时到达, TrueTime at nodeB=[0,7](注意:真实时间间隔始终包括 实时)。
  2. trxA 由nodeA 提交,TransactionCommitTime=8 (可能是 7 并且 >= TT.Latest),TrueTime 位于 nodeA=[8,8]
  3. trxB 在 RealTime=9ms 时到达 NodeB,TrueTime 在 NodeB=[2,9]
  4. trxB 由nodeB提交,TransactionCommitTime = 9(TT.Latest)并且 Spanner 将等待 7ms,然后释放锁并返回响应 向客户确保事务提交时间 (9) 更短 比当前 TT.最早。

因此,如果客户端在收到 TxnA 的响应后发送 TxnB,则 TxnA 的提交时间戳将始终小于 TxnB 的提交时间戳。

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