混合时钟

结合系统时间戳和逻辑时间戳,将版本表示为日期和时间,以便排序

问题

Lamport 时钟用作版本化值中的版本时,客户端不知道特定版本存储的实际日期和时间。对于客户端来说,使用日期和时间(如 01-01-2020)而不是整数(如 1、2、3)来访问版本会更方便。

解决方案

混合逻辑时钟提供了一种方法,可以使版本像简单的整数一样单调递增,但同时也与实际日期和时间相关。混合时钟在实践中被 MongoDB 或 CockroachDB 等数据库使用。

它将最新时间维护为混合时间戳的实例,该实例由系统时间和整数计数器构成。

class HybridTimestamp…

  public class HybridTimestamp implements Comparable<HybridTimestamp> {
      private final long wallClockTime;
      private final int ticks;
  
      public HybridTimestamp(long systemTime, int ticks) {
          this.wallClockTime = systemTime;
          this.ticks = ticks;
      }
  
      public static HybridTimestamp fromSystemTime(long systemTime) {
          //initializing with -1 so that addTicks resets it to 0
          return new HybridTimestamp(systemTime, -1);
      }
  
      public HybridTimestamp max(HybridTimestamp other) {
          if (this.getWallClockTime() == other.getWallClockTime()) {
              return this.getTicks() > other.getTicks()? this:other;
          }
          return this.getWallClockTime() > other.getWallClockTime()?this:other;
      }
  
      public long getWallClockTime() {
          return wallClockTime;
      }
  
      public HybridTimestamp addTicks(int ticks) {
          return new HybridTimestamp(wallClockTime, this.ticks + ticks);
      }
  
      public int getTicks() {
          return ticks;
      }
  
      @Override
      public int compareTo(HybridTimestamp other) {
          if (this.wallClockTime == other.wallClockTime) {
              return Integer.compare(this.ticks, other.ticks);
          }
          return Long.compare(this.wallClockTime, other.wallClockTime);
      }

混合时钟可以像Lamport 时钟版本一样使用。每个服务器都保存一个混合时钟的实例。

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

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

2023 年 11 月 23 日