基本概念可以查看下面的参考链接
Lamport Lock
一张图表示自己的理解:
Vector clock
上图可以看出,ta<tb并不能推出a happens before b
vector clock的引进就是来解决这个问题的
简单比较
1.如何比较大小?
vector clock:
vp<vq 如果 vp[i] < vq[i] 对所有i均成立
存在i 使得vp[i] < vq[i] and 存在j 使得 vp[j]>vq[j]那么就是并发的
lamport clock:
(p,i)<(q,j)如果i<j;(p,i)<(q,i)如果p<q
2、全序?偏序?
vector clock 是偏序关系;lamport clock是全序关系
应用
那么这么一个算法本质上是为了给分布式系统提供全局的逻辑时钟,保证各个副本执行的操作是一样的。
再举例之前,先做几点说明:
1、参考原始论文的5条规则(参考链接1)
1.首先,每个进程会维护各自在本地维护一个请求队列。算法是由如下5个规则定义的。方便起见,每条规则定义的行为会被做为一个独立事件。
为请求该项资源(在这个问题中,资源就是日志服务器),进程Pi发送一个(Tm,Pi)
2.资源请求消息给其他所有进程,并将该消息放入自己的请求队列,在这里Tm代表了消息的时间戳
3.当进程Pj收到(Tm,Pi)资源请求消息后,将它放到自己的请求队列中,并发送一个带时间戳的确认消息给Pi。(注:如果Pj已经发送了一个时间戳大于Tm的消息,那就可以不发送)
4.释放该项资源时,进程Pi从自己的消息队列中删除(Tm,Pi)资源请求,同时给其他所有进程发送一个带有时间戳的Pi资源释放消息
5.当进程Pj收到Pi资源释放消息后,它就从自己的消息队列中删除(Tm,Pi)资源请求
当同时满足如下两个条件时,就将资源分配给进程Pi:
(i)按照“=>”关系排序后,(Tm,Pi)资源请求排在它的请求队列的最前面
(ii)Pi已经从所有其他进程都收到了时间戳>Tm的消息
2、在利用Lamport Timestamp实现全序组播时,要遵循如下假设:
(1)进程Pj在接收进程Pi的消息时,Pj对消息的接收顺序与Pi发送消息的顺序一致
(2)任何传输的消息不会丢失
例子:
一个等价的问题就是如何在分布式系统下实现全序组播(totally-ordered mulitcast)。这个可以利用Lamport提出的逻辑时钟实现。
保证全序组播的具体算法为:
每一个进程都维护一个本地请求队列(Request Queue),此队列里的消息按时间戳排序。
进程Pi给消息m加上时间戳Ti(m),并广播给所有进程(包括Pi);
进程Pj接收到消息m后,首先更新本地逻辑时钟,并把消息m加入请求队列,然后向
所有进程(包括Pj)广播接收到消息m的确认信息ACK。
当进程的请求队列中的某个消息位于队列顶部,且已经收到所有进程关于此消息的
确认信息ACK时,可以把此消息从队列顶部取走,并传给应用程序。
上述算法结合假设,可以证明所有进程都按相同的顺序执行一组操作。
证明中的关键点:
当进程Pi收到所有关于消息m的确认信息ACK时,
首先,可以确认其他进程已经收到了消息m;
其次,可以确认其他进程中“在关于消息m确认信息ACK之前发的消息”进程Pi都
已接收(这个可以从假设得到)。这表明如果存在需要在消息m之前执行的消息,
进程Pi已经接收了,否则与假设矛盾。结合消息的执行条件,就能保证消息m不会
被提前执行。
最后,由于每个进程是等价的,所以每个进程的请求队列都是一致的。
例子2:
其实logic clock要解决的问题就是多点共同更新的问题,每个节点都保存有完整数据,所以操作要全局同步。
比如,lamport clock就是保证每个节点的任务队列的一致性,当然原始paper有一些假设和规则来达到这个目的,不过思想是没问题的。
比如上面的例子同样适用于多点更新(如银行数据),只需要利用上面算法保证每个节点事务执行的顺序就行了
小结
- 可以看出,上述算法都是固定的线程数
- 如果有一个hang住了,系统会阻塞
- 解决的是最终一致性问题
- 关于vector的应用优势:
vector clock是logic clock的一种,并且是目前被证明的能精确进行冲突检测的最有效的数据结构(有没有更有效的?答案是有,后面会介绍,但是精确度会下降).它的原理就是所有允许写入的节点维护一个counter,每次本地提交的动作会导致value+1并把这个值由本次操作携带,同步到其他节点去.远端节点在收到请求后也会为该操作分配一个本节点最新的counter.所以某个操作会在N-master集群中得到一个N个值的数组,只有当所有节点上的操作A的counter都小于对应节点上操作B的counter的时候才认为他们具有明确的happen-before,否则视为冲突.
而我们所说的Lamport clock是一种scalar clock,可以决定时序,但是任何的scalar clock并不能检测冲突.因为counter(A)<counter(B)并不能要求A操作先于B.所以在Lamport clock中即使产生并发,也有可能是有序的,无法检测到.这是dynamo系统不允许发生的,所以这类系统会考虑使用vector clock.
vector clock有一个很大的缺点是不够高效,因为N-master集群需要N个元素来做判断,这对于集群的拓展会有损害.对于消息传递需要携带过多的payload也是不小的开销.这时候又出现了一种plausible clocks,可以在常量个vector元素的情况下,很高概率检测出来冲突,但并不是100%.但是这种模型只适合用于对于并发进行排序会提升效率的系统中,而不是影响正确性的系统中.
参考
Lamport大师的论文
Seif Haridi
logical clock lmaport vector-一个简单的pdf教程
国人解释-可以参考
分布式系统一致性系列