Lamport 时钟

使用逻辑时间戳作为值的版本,以允许跨服务器对值进行排序

问题

当值存储在多个服务器上时,需要一种方法来了解哪些值是在其他值之前存储的。系统时间戳不能使用,因为它们不是单调的,并且不应该比较来自两个不同服务器的时钟值。

系统时间戳表示一天中的时间,由通常使用晶体振荡器构建的时钟机制测量。此机制的已知问题是它可能会偏离一天中的实际时间。为了解决这个问题,计算机通常具有诸如 NTP 之类的服务,该服务将计算机时钟与互联网上的参考时间源同步。因此,在给定服务器上对系统时间的两次连续读取可能会出现时间倒退的情况。

由于服务器之间没有时钟漂移的上限,因此无法比较两个不同服务器上的时间戳。

解决方案

Lamport 时钟维护一个数字来表示时间戳:每个集群节点维护一个 Lamport 时钟的实例。

每当服务器执行任何写操作时,它都应该使用 `tick()` 方法推进 Lamport 时钟。

class LamportClock

  public int tick(int requestTime) {
      latestTime = Integer.max(latestTime, requestTime);
      latestTime++;
      return latestTime;
  }

通过这种方式,服务器可以确保写入是在请求之后以及服务器自客户端发起请求以来执行的任何其他操作之后进行的。服务器将用于写入值的时戳返回给客户端。然后,请求的客户端使用此时间戳向其他服务器集发出任何进一步的写入。这样,就维护了请求的因果链。

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

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

2023 年 11 月 23 日