逻辑时钟的性质
逻辑时钟首次在Lamport于1978年发表的《Time, clocks, and the ordering of events in a distributed system》中被提出,引用量过万,可谓是分布式系统中时钟同步的奠基者。
- 为了方便,我们将分布式系统中的节点简称为一个个的进程
- 逻辑时钟提出的目的主要是为了维护分布式系统中,事件发生的因果关系。那么什么叫因果关系呢?
- 第一种因果关系:同一进程中,事件发生的先后关系可以决定它们在时钟上的偏序关系
- 第二种因果关系:不同进程间,时间的发送-接收关系也可以决定在时钟上的偏序关系
为了更好地理解以上的因果关系,我们用下面这个例子来说明:这张图描述的是,两个进程A和B同时维护数据库中数据X的备份。(更新数据表示将数据X写回到数据库)
- A1 -> A2 -> A3,以及 B1 -> B2,这两条事件链就构成了上述的第一种因果关系,即下图中的绿色线。
- A2 -> B1 则构成了上述的第二种因果关系,即下图中的红色线。
用 C ( P ) < C ( Q ) C(P)<C(Q) C(P)<C(Q)表示事件 P P P和事件 Q Q Q在时钟上的偏序关系,则图1、2中的更新事件存在以下偏序关系:
- C ( A 1 ) < C ( A 3 ) C(A1)<C(A3) C(A1)<C(A3)
- C ( A 1 ) < C ( B 2 ) C(A1)<C(B2) C(A1)<C(B2)
注意:若事件P和Q之间存在因果关系,则它们在时钟上存在偏序关系。(即偏序关系是因果关系的必要非充要条件)
逻辑时钟的构建
- 对进程内部:当要发生一个新事件时,保证本地逻辑时钟至少更新一次(即+1)
- 对进程间通信:
- (发送进程)将发送时间(即发送时的本地逻辑时钟)附在消息中
- (接收进程)若消息中时钟大于本地时钟,更新为消息中时钟+1;否则更新为本地时钟+1
图3展示了将逻辑时钟用于上述场景时,逻辑时钟的值:
逻辑时钟存在的缺陷
在使用逻辑时钟的系统中,只有两个事件存在因果关系时,逻辑时钟的大小关系才有用处。也就是说,若两个事件没有因果关系,则逻辑时钟的大小关系无意义。即无法从逻辑时钟上的偏序关系反推事件的因果关系(必要不充分条件)。
为了更好地理解这个缺陷,我们用下面这个图作为例子解释:
- 在图3中,事件A3发生在B2之前,且 C ( A 3 ) < C ( B 2 ) C(A3)<C(B2) C(A3)<C(B2),所以数据收到这两个事件时,是可以按照正确顺序执行地。
- 但在图4中,事件A3发生在B2之后,且 C ( A 3 ) < C ( B 2 ) C(A3)<C(B2) C(A3)<C(B2),所以数据库收到两个事件提交时,会先执行A3,然后再执行B2。而这就造成了错误。
那么怎么改进这个缺陷呢?这就要用到 向量时钟 或者 混合逻辑时钟了(Hybrid Logical Clock) 了。