1,导论
①如何在分布式环境下定义系统中所有事件的发生顺序?②分布式环境下多个进程竞争资源时如何互斥?③什么是偏序,偏序的作用是什么,有什么不足?④什么是全序,全序的作用是什么,有什么不足?⑤为什么需要物理时钟,物理时钟如何同步?下面来进行介绍。
2,偏序的定义、发生在先(happened before)关系
考虑单一的进程A,在某时刻发生了事件E1,经过一段时间后,发生事件E2,可以说:E1发生在E2前面。考虑多个进程,进程A向进程B发送消息,进程A发送消息时记为事件E1,进程B接收到进程A发送的消息记为E2,可以说:E1发生在E2前面。以上两个例子表明了E1与E2是一种偏序的关系。之所以说明这两个例子所代表的关系是偏序的,是因为:当需要判断下图中的 a 和 e 这两个事件谁先谁后时,在偏序关系下是无法判断的。
偏序的定义:(1)若a,b 是同一进程中的两个事件,且 a 发生在 b 之前,则 a ---> b (---> 符号 表示 发生在先 关系, !---> 符号 表示 非发生在先 关系)
(2)若 a 是 "一个进程发送消息 "事件,b 是一个进程接收消息事件,则 a ---> b
(3)若 a !--->b and b!---> a ,则称 a、b是并发的。如上图中 事件a 与 事件e 就是并发的。
发生在先关系即偏序的代名词。
3,全序
在 2 中,由于偏序不能表示 图中事件a 和 事件e 的先后关系,而在分布式系统中对所有的事件排序又是必须的,因此就需要另一种方法来定义所有事件的顺序,即用Lamport 逻辑时钟来定义分布式系统中所有事件的全序。
“引用自网络” Logical Clock解决的问题是找到一种方法,给分布式系统中所有时间定一个序, 这个序能够正确地排列出具有因果关系的事件(注意,是不能保证并发事件的真实顺序的) ,使得分布式系统在逻辑上不会发生因果倒置的错误。
Lamport 逻辑时钟如下:
首先定义一个Clock Condition:如果 a ---> b ,则 C(a) < C(b)(C(a)可以理解成事件a的"发生时刻")。再给出两个条件C1和C2,C1定义:若 a,b是同一进程i中的两个事件且 a---> b,则 Ci(a) C2定义:若事件a代表发送消息的进程i 发送消息,事件b代表接收进程j接收该消息,则Ci(a) < Cj(b)。显然,当条件C1与C2成立时,Clock Condition是成立的。 在C1 和 C2 的基础上,再定义两个处理操作:IR1 和 IR2 (参考论文中的描述)。IR1、IR2 的本质就是,在同一进程中,a 在 b 之前发生 ,则需要设置 b 的时间戳大于 a的时间戳;在不同进程之间发送消息时,设置接收消息的事件的时间戳要 大于 发送消息这一事件的时间戳。 全序的定义: 各个进程间发生的事件的全序定义,可采用不同的方式。即论文中提到的 arbitrary total ordering. 理解如下:比如,可以把各个进程之间标序号。如1,2,3,4……当进程之间有并发的事件时,规定序号小的进程相应的事件 发生得早。比如上图:设进程P的序号为1,进程Q的序号为2,对于事件e和事件a而言,就认为 事件e “早于” 事件a 发生。 这样,由IR1 和 IR2 这两个操作,再加上 将各进程标序号这种方式 就可以对所有的事件定义一个全序了,这样就解决了在分布式系统中如何对所有事件排序这一问题。上图的一个全序如下: (1:1,e)---(1:2,f)---(2:1,a)---(2,2,b) 格式解释:(进程序号:事件顺序号,事件名称) 在这里出现了一个小小的问题:(1:2,f)---(2:1,a)???----可能是向量时钟需要解决的吧??? 4,分布式环境下,多个进程之间竞争资源如何互斥? 现有一临界资源,对它的访问要求如下: ⓐ占有资源的进程,在它将该资源授权其其他资源时,必须先释放该资源 ⓑ对资源的授权必须按照 提出资源请求的顺序 进行。即,若进程A先于进程B申请资源(有全序关系的保证,当然就知道请求的先后顺序了),那么在分配资源时,应该将资源先分配给A用。 ⓒ对任何已获得资源的进程,最终会释放资源;也即,任何进程发生的 申请资源的请求最终会被响应。换句话说,占有资源的进程最终会使用完该资源并释放(不会死锁),这样就保证了任何资源请求最终会被响应。 如何解决该问题呢? Lamport 大师提出了一个算法如下: ❶若要请求资源,进程Pi需要发送一个格式为 Tm:pi 的请求消息给系统中的其他所有进程,并将该消息放入自己的请求队列中。(Tm表示消息的时间戳) ❷当其他进程如Pj收到 Tm:pi请求后,将它放到自己的请求队列中,并发送一个带有时间戳的确认给pi。 ❸释放资源时,pi从自己的消息队列中删除所有的 Tm:pi请求,并向其他所有的进程发送带有时间戳的 pi资源释放消息。 ❹当其他进程,如pj收到pi的资源释放消息时,pj从自己的消息队列中删除所有的 Tm:pi请求消息。 ❺若同时满足如下两个条件,则将资源分配给进程pi: a)按照 全序 关系 排序后, Tm:pi请求 排在它的请求队列的最前面---即,在进程pi中, Tm:pi资源请求消息是最先 发生的。 b)pi 收到了所有其他进程发给它的时间戳大于Tm的消息 根据算法的❶❷❸❹❺能够证明ⓐⓑⓒ是成立的。 部分证明的理解如下: 证明ⓐ的成立:反证法。 假设ⓐ不成立,则意味着在资源分配给某进程后,假设该进程为Pm,还有其他进程未释放该资源,假设为Pn,那么对于这个进程来说,意味着它还未释放资源,根据❸❹,也就意味着它还未将该请求从自己的队列中删除,同时,由❸可知,pm中还存储着pn请求资源的消息。而进程Pm之所以能获取资源,说明它满足了❺的两个条件,但是根据❺的条件a)说明进程Pm的资源请求是最早的,但是实际上Pn的请求要更早,因为它比Pm更早获得授权,但是该请求还未从Pm的队列中删除,因此❺的条件a)就不可能满足,这样就找到了矛盾的地方。 证明ⓑ的成立: 根据❺的a)可知,资源的分配是按照 发生资源请求的 全序关系排序的,单独考虑pi进程发出的资源请求而言,由全序关系 ,排在队列前面的请求先得到满足。再由❺的b),pi收到所有的其它进程发过来的请求,意味着pi知道了其他进程的事件请求操作情况,因此,它就知道了当前它的Tm:pi 请求在整个系统中是不是最早的,而❺的b)中:pi 收到了所有其他进程发给它的时间戳大于Tm的消息,这样它就确定Tm是最早的资源申请请求了,就会给Pi的Tm:pi 请求分配资源。 因此ⓑ成立 证明ⓒ的成立: 根据❸❹❺可请证明ⓒ成立。假设pi已经拥有的资源,它发送一个带时间戳的资源释放请求给其他所有进程,其它进程就把当初进程pi请求资源时发送给它们的消息从队列中删除(参考❹),这样使得其它进程(非pi进程)的请求队列中资源请求消息变成最早的了(因为,最最早的pi资源请求消息已经被删除了),这样就使得任何进程发出的资源请求消息最终能够被响应。 5,逻辑时钟存在的问题(Anomalous Behaviour)以及引入物理时钟的原因 采用上述讨论的逻辑时钟还不能完成给事件排序。考虑下面一个情况:小A 在 A市 的计算机A上发送了一个请求A,然后打电话告诉 住在B市的小B,让小B 在计算机B上产生一个请求B。在现实的物理世界中看出是请求A导致了请求B的发生,即A是因,B是果。但在逻辑时钟系统下,可能会出现A的时间戳排在B的时间戳的后面。为啥?因为“打电话”这一手段可以理解为是在逻辑时钟系统外部发生的。比如请求A在标号为2的进程上发生,而请求B在标号为1的进程上发生,排全序时,请求B的时间戳会小于请求A的时间戳。 如何解决这样的情况?一种解决思路是把“打电话”这一事件也加入到系统中来考虑。这时,单纯地用Lamport 逻辑时钟就不能对所有的事件进行全排序了。因此,就引入了物理时钟来解决该问题。 其次,对于逻辑时钟而言,是没有错误概念这一说的。failure这个概念只有在物理时间上下文中才有意义,如果没有物理时间,就没有办法去区分进程是出错了还是只是处于事件之间的间隔之中。用户只能通过系统很长时间都没有响应来判断系统出了问题。 引入物理时钟之后,物理时钟的正确工作是需要一定的条件的,即各个计算机使用的物理时钟值不能偏差太大。因此,又提出了物理时钟同步。物理时钟的同步主要有两种方式:1)有一个标准的时间服务器,各个Client都去连接该时间服务器同步时钟,从而达到各个Client的时钟是同步的。2)Berkeley算法:时钟服务器主动地询问各个Client的当前的时钟值,各个Client就会告诉时钟服务器它们各自的时钟是多少,时钟服务器把收集到的这些值,再加上自己的时钟值,得出一个平均值。并计算出各个Client的时钟值与该平均值的差值,时钟服务器把该差值分别发送给各个Client,让它们进行调整。 如:Client A 比平均值少5秒,则Client A 需要加快自己的时钟计数(并不是把自己的时钟值倒退5秒),其实相当于物理学中的将加速度增大了。 6,Lamport逻辑时钟的局限性 a)使用逻辑时钟的方法给所有的事件排序时,必须保证所有的进程都参与其中(参考上面的算法描述),即不容许进程失败。而这在现实的分布式系统中几乎是不可能的。b)该算法假设消息是按序到达的,且一定会传递成功。这可以通过消息序号和确认机制来保证(TCP协议)。 总结:在分布式系统中,讨论各个事件的发生顺序时,一般讲的都是偏序!! 7,参考文献 《time clocks and the ordering of events in a distributed system》论文 全序, 分布式一致性的本质 我对Lamport Logical Clock的理解Time Clocks and the Ordering of Events in a Distributed System(译文)