时钟绑定等待

等待跨集群节点的时间不确定性,然后再读取和写入值,以便跨集群节点正确排序值。

问题

考虑一个键值存储,其中值与时间戳一起存储以指定每个版本。处理客户端请求的任何集群节点都能够使用请求处理节点的当前时间戳读取最新版本。

在下图中,值Before Dawn在时间 2 按照 Green 的时钟更新为值After Dawn。Alice 和 Bob 都试图读取title的最新值。当 Alice 的请求由集群节点 Amber 处理时,Bob 的请求由集群节点 Blue 处理。Amber 的时钟滞后于 1,这意味着当 Alice 读取最新值时,它会提供值Before Dawn。Blue 的时钟为 2,因此当 Bob 读取最新值时,它会将值返回为After Dawn

这违反了所谓的外部一致性。如果 Alice 和 Bob 现在打电话,Alice 会感到困惑:Bob 会告诉她最新值为After Dawn,而她的集群节点显示的是Before Dawn

如果 Green 的时钟很快,并且写入按照 Amber 的时钟发生在未来,也是如此。

如果系统的时间戳用作存储值的版本,这是一个问题,因为系统时间戳不是单调的。来自两个不同服务器的时钟值不能也不应该比较。当混合时钟用作版本化值中的版本时,它允许在单个服务器上以及在因果相关的不同服务器上对值进行排序。但是,混合时钟(或任何其他类型的Lamport 时钟)只能给出“偏序”。这意味着任何不是因果相关的并且由跨不同节点的两个不同客户端存储的值都无法排序。这在使用时间戳跨集群节点读取值时会产生问题。如果读取请求源自时钟滞后的集群节点,它可能无法读取给定值的最新版本。

解决方案

在读取或写入时,集群节点会等待,直到集群中每个节点上的时钟值都保证高于分配给该值的时钟值。

如果时钟之间的差异很小,写入请求可以等待而不会增加太多开销。例如,假设跨集群节点的最大时钟偏移量为 10 毫秒。(这意味着,在任何给定时间点,集群中最慢的时钟最多比最快的时钟滞后 10 毫秒。)为了保证其他每个集群节点的时钟都超过时间t,处理任何写入操作的集群节点将不得不等到t + 10 毫秒才能存储该值。

有关更多详细信息,请访问 oreilly.com 上的在线电子书第 24 章

此模式是分布式系统模式的一部分

2023 年 11 月 23 日