在现实世界里,想要知道此时是几分几秒好像并不是什么难事儿。可是对电脑来说,事情却并没有那么简单。现代计算机系统中,对于时间流逝的感知和量度,大部分来自石英晶体振荡器。这是利用石英晶片的压电效应制造的电子元件。当晶片在交变电压的作用下产生谐振时,振荡器可以输出稳定度较高的振荡频率。之所以说稳定度较高,是因为它并不是以绝对恒定的频率在振动。
在各方面的影响下,总会出现振荡频率比元件声称的频率稍高或稍低的状况。这种偏差反映到系统时钟上,就是系统时钟比标准时间稍快或者稍慢。
如果所有的任务和作业都是在单个计算机上完成的,似乎系统时钟稍快稍慢并不是很严重的事情。我们可以设想这个稍快或者稍慢的计算机就像是一个独立的世界。在这个世界中,因为时钟速率不同,带来的影响也只不过是各种事件发生得更快或者更慢。该发生的终究都会发生,事件的因果先后顺序也都还在。只要不需要和外部世界的时间作协调同步,那这里就像一个平行宇宙一样,冷暖自知。
但如果是分布式系统的话,情况就不一样了。所谓分布式系统,简单来看就是由多台计算机组成的系统,这些计算机通过网络相互通信,共同协作完成任务。现如今的互联网,各式的云服务,搜索引擎,以及微信微博等的社交软件,在它们的背后都是一个分布式系统。理想情况下,我们当然是希望系统内的所有计算机对此时此刻是什么时间以及时间过得有多快都有一个共同的概。
要同步系统内所有计算机的时钟,首先,自然的想法是让系统内的计算机都跟同一个更可靠的时钟源做校准。这种方法可行,但并不足够好。来自谷歌的一篇文章提到说,他们自己数据中心的所有服务器会有200百万分率(ppm, parts per million)的时钟偏差。即,如果所有机器每30秒做一次校准的话,机器还是会有6毫秒的偏差;如果每天做一次的话,偏差则会有17秒之多。
这个校准后的差值,部分来自于晶振本身的频率波动,其实还有一部分来自时钟校准的过程。
网络时间协议(NTP)是计算机之间进行时间校准的标准协议,它的工作原理大致如下:可靠时钟源会记录本地的时间T₁和T₂, 并通过回复信息返回给请求者,请求校准的计算机自己记录下T₀和T₃, 最终较可靠的时钟源跟本地时钟的偏差为:((T₁﹣T₀)﹢(T₂-T₃))/ 2。
这个计算是带有一个假设的,就是请求的发送和回复的回传在网络通信上的延迟是相等的,这个计算希望通过分子中的两项相加来把这个通信延迟项给抵消掉。
莱斯利·兰波特(Leslie Lamport)在他1978的一篇论文中阐述了这一观点并提出了逻辑时钟这个概念。他的想法是,我们可以把时钟看作一个函数,函数的输入是系统中的事件,输出是一个数,是这个“逻辑时钟”赋予这个事件的“逻辑时刻”。这个“逻辑时刻”不必须和物理世界里的时间有任何关系,它可以只是一个计数器的值。像在现实世界中一样,我们通过比较这些“时刻”的大小来判断事件发生的次序。
在文章中,兰波特使用了很多时空图来进行分析。显然他从物理的相对论里也汲取了不少灵感。他说:“在相对论中,事件的顺序是通过有可能被传递的信息来定义的。然而,我们采用了一种更加务实的方法,那就是只考虑那些真正被发出的信息。我们应该可以只通过系统中确实发送了的信息,而不是那些有可能被发送的信息,来断定这个系统是否在正确地运转”。
2013年,兰波特获得了图灵奖,为了表彰他在并发和分布式系统领域所做的基础性贡献。本文中的“逻辑时钟”就是其中重要的一部分。