原标题:技术分享:Lamport逻辑时钟
前言
《Time, Clocks, and the Ordering of Events in a Distributed System》是Lamport老哥的论文,这篇论文在1978年7月发表在《Communication of ACM》,于2000年获得了首届PODC最具影响力论文奖,于2007年获得了“ACM SIGOPS Hall of Fame Award”。这篇论文被多次进行引用,里面提出了分布式系统中的多个关键概念,例如:事件先后的happen-before,定义关联事件顺序的偏序关系,定义所有事件顺序的全序关系,逻辑时钟,物理时间的同步,分布式互斥算法,state machine等等。
本文中我们只涉及逻辑时钟相关部分。
狭义相对论
说出来你可能不信,计算机领域的论文里会出现相对论,但是实际上据说作者就是从物理学中获得的灵感。在狭义相对论中,认为随着参考系的变化,观测到的事件发生顺序有可能发生变化。比如下图中,有一辆运动的车辆,t=0时,车辆的中心向两边发射一束光线。在车上的人看来,光速到底两端的事件是同时的,在车下的人看来,光先到底车尾,后到达车头。
但是如果事件之间发生了关联,即两个事件有因果关系,那么因果关系会得到保留。
更多相关内容,请参考相对论相关文章。
在分布式的系统当中,很难取得精确的物理时间,作者提出了逻辑时钟来判断事件的因果关系,来决定事件的先后顺序。
happen before偏序关系
首先作者定义了happen before的偏序关系。定义happen before关系-满足如下条件:
事件a和b在同一个进程中发生,a在b之前发生,那么a-b
事件a是发送信息,事件b是接收该信息,那么a-b
a-b并且b-c,那么a-c如果即不存在a-b,也不存在b-a,那么a和b是并发的。
作者用上面这个图片展示了时序关系,竖直方向代表时间,从下向上增长,圆点代表事件,波浪线代表发送消息。可以看出p1-r4,但是p3和q3是并发的。
逻辑时钟
定义Ci作为进程Pi的时钟,Ci(a)用来给事件a产生一个数字,代表事件的时间。
定义C作为系统的时钟,如果事件b属于进程Pi,那么C(b)=Ci(b)
系统内时钟条件如下:如果a-b,那么C(a) C(b)。
注意反之则不然,因为那样会推导出对于并发的两个事件a和b,存在C(a)=C(b)。上图中p2和p3都和q3并发,就意味着C(p2)=C(p3),这显然不合理。
从-的定义可以推出如下结论:
事件a和b在同一个进程Pi中发生,a在b之前发生,那么Ci(a) Ci(b)
事件a是进程Pi发送信息,事件b是进程Pj接收该信息,那么Ci(a) Cj(b)为了实现逻辑时钟,假设每个进程i有个变量Ci,用来产生事件的时间。Ci按如下规则变化:
每个进程i在节点内事件发生时将Ci递增
假设事件a是进程i发送消息m的事件,m需要携带时间戳t=Ci(a);进程j接收到m之后,将Cj设置为比t大并且不小于Cj当前值的值作为一个实现,我们设置Ci的初始值为0,并且:
每个进程i在节点内事件发生时将Ci加1
假设事件a是进程i发送消息m的事件,m需要携带时间戳t=Ci(a);进程j接收到m之后,将Cj设置为max(t,Cj)+1全序关系
有了逻辑时钟,我们可以定义所有事件的全序关系了。注意,因为存在两个事件的逻辑时钟一致的情况,所以这里在先任意的选择一个进程全序关系-,例如我们可以将进程编号的大小关系作为-。
进程i中的事件a和进程j中的事件b的全序关系=定义为满足如下任意条件时,a=b:
Ci(a) Cj(b)
Ci(a) = Cj(b) 并且 Pi-Pj值得注意的是,这个全序关系不是唯一的,和-的选择有很大的关系。
后记
在论文的后面,作者还介绍了用事件全序关系和state machine实现的分布式互斥算法和时钟同步算法,有兴趣的读者可以自行参阅。返回搜狐,查看更多
责任编辑: