分布式系统中的时钟
我们常常在人生的大部分时间里,对事物的运作方式一无所知。大多数时候,这没什么大不了的,因为我们并不需要真正了解周围的一切是如何运作的。但有时,我们会意识到有多少复杂性被隐藏起来,被抽象出来,被巧妙地藏起来,以至于我们永远不需要去思考它们。
最近,我突然意识到,我竟然从未认真思考过一个我每天都在工作的小事:时间!我这辈子大部分时间都在使用电脑,一开始是科技的消费者,后来成了科技的创造者。直到我开始学习分布式系统(为了这个系列!),我才意识到,我对报时机制的了解远不如想象中那么多,更不用说我们每天使用的电脑是如何决定时间的了。
说到分布式计算,时间就是一个完全不同的概念。但在真正深入探讨分布式系统中的时间之前,我们首先需要了解单个机器是如何追踪时间的。那么,让我们开始了解究竟是什么让时间变得如此棘手。
追踪时间
如今,大多数设备都具备日期和时间的概念。除了一些“物联网”设备(例如树莓派),所有机器都具备时间概念。但它们是如何确定日期和时间的呢?

答案是:用时钟!乍一看,这似乎显而易见,但随着我们进一步理解,就会发现其中的奥妙。需要报时功能的计算机通常会内置一个时钟,它以集成电路的形式嵌入到硬件中。这个电路通常直接安装在主板上。这个小小的硬件被称为实时时钟(RTC)。
RTC 尤其有趣,因为它们配备了备用电源(例如电池),即使机器断电也能继续工作!这在今天看来或许显而易见,但 RTC 的使用在计算机发展史上却是一个相当重要的里程碑;早期的个人电脑实际上并没有内置 RTC,后来才被添加进来。现在,我们会发现冰箱和微波炉里都内置了这些小时钟!想想就觉得不可思议。
RTC 负责跟踪当前时间,我们可以将其视为一台机器的系统时钟。需要注意的是,该时钟特定于机器的“系统”;换句话说,机器执行的任何依赖于时间的进程、任务或工作都将固有地依赖于系统时钟指示的时间。
那么,这个物理时钟究竟是如何工作的呢?原来,在集成电路的深处有一个晶体,它会振动或振荡;它被称为晶体振荡器。

我们无需深入探究其背后的物理学原理,就我们的目的而言,我们真正需要知道的是,时钟可以捕捉并计数晶体的振动。当晶体振动时,时钟以滴答声的形式记录每次振动,通过一次又一次的计数,时钟便可跟踪时间。当然,这引出了一个问题:时钟在哪里记录它所记录的每个滴答声。物理时钟使用二进制计数器电路(一种只进行二进制计数的简单电路)来存储这些滴答声。方便的是,机器从二进制计数器电路(系统时钟)获取系统时间。事实上,正如机器有系统时钟一样,它也有基于该时钟的时间概念!

系统时间的一个有趣之处在于,它总是根据系统时钟的开始时间计算时间。这意味着,如果我们将新电脑上的系统时钟设置为慢五分钟或快两天,那么我们系统时间的起点,或者说我们开始计时的“零点”,最终要么慢五分钟,要么快两天。换句话说,我们将根据我们设定的日期或时间来测量“滴答”,而不是实际时间。

为了避免这个问题带来的一些混淆,大多数机器在决定起点时都遵循某种约定。例如,搭载 Unix 操作系统的机器已经标准化了Unix 时间,这是一种决定我们开始计算时间的“零点”应该在哪里的方法。对于 Unix 时间,起点或“零点”是Unix 纪元的开始,即 1970 年 1 月 1 日 00:00:00 UT(世界时)。纪元应该是任意的;它只不过是我们开始测量时间的约定起始日期和时间。我个人最喜欢的纪元是 Microsoft Excel 程序的纪元,即 1990 年 1 月 0 日!(对于对纪元好奇的人,请查看这个详尽的列表。)
不同步,失控
既然我们知道时钟可以在任意时间开始“计数”,那么现在该添加另一个因素了。也就是说,如果我们有多个时钟会发生什么?这时,事情就开始变得有点不同步了。

由于每台机器都有自己的时间概念,我们可以假设两台不同的机器对时间的概念也各不相同。但事情由此开始变得有点复杂:如果两台不同的机器对时间的概念不同,我们又如何确定它们是一样的呢?
不幸的是,计算机时钟并不一致。
我们已经知道,每个时钟对于开始计数的时间和“零点”都有不同的理解,而且一个时钟可能与另一个时钟不一致。然而,值得一提的是,并非所有时钟都是精确的,有些时钟比其他时钟更精确。随着时间的推移,时钟每一次“滴答”的精确度确实会开始影响时钟如何计时。

例如,典型的石英钟会在11或12天内出现大约一秒的误差。这是由于石英钟在走时测量一秒的时间时,会产生微小的误差。一秒的误差看似微不足道,但随着时间的推移,微小的误差就会累积起来!时钟的精确度可能会受到温度、位置、时钟电源,甚至时钟的制造工艺的影响。

这种由于时钟精度有限而导致两个时钟计时不同的现象被称为时钟漂移。不幸的是,任何需要自行追踪时间的机器都会遇到这种情况。由于时钟漂移非常常见,我们经常会比较两个显示不同时间的时钟。这被称为时钟偏差,指的是两个时钟之间的时间差。
在一个完美的世界里,两个时钟的时间一致,我们永远不会遇到这两个问题!在这样的乌托邦里,时钟漂移和偏差都为零。
可惜,我们并非生活在这样的世界,所以在比较两台不同的机器及其时间时,我们必须同时考虑这两点。相反,我们生活在一个混乱且……分布式的世界。
没有一个时钟可以统治一切
我们已经讨论了很多关于时钟、它们的工作原理以及它们之间如何产生不一致的问题,但这与分布式系统究竟有什么关系呢?事实证明,所有这些关于时钟的讨论都指向了分布式系统的核心基础原则之一,而不知何故(!)我们却从未涉及过它。现在,终于到了讨论它的时候了。

众所周知,在分布式系统中,所有单独的组件都称为节点,它们各自独立,能够执行各自的工作。我们还了解到,每个节点都有自己的时间概念,并在内部跟踪自己的时间。将这两个事实结合在一起,我们得出一个结论:
分布式系统中没有真正的全局时钟。
系统中的每个节点都有自己的时间概念,分布式系统中没有一个中心化的位置来让节点确定实际时间。如果我们不那么在意时间,这或许就无关紧要了!我们在计算中频繁使用时间,尤其为了确定某个事件何时发生,以及哪个事件在另一个事件之前发生。

那么,如果分布式系统中没有全局时钟会发生什么呢?首先,我们无法知道任意两个事件发生的实际时间,也无法知道它们发生的顺序。这使得我们很难确定这两个事件在未来的调度安排。这也使得分布式系统很难调试,因为我们无法确定一个事件是否在另一个事件之前发生!
我们将在接下来的文章中更多地讨论时间和事件的顺序,希望我们能找到一些行之有效的解决方案来解决这个问题。在那之前,尽量不要看手表,也不要过多地考虑时间。
资源
分布式系统中的时钟和时间可能是最难理解的概念之一——尤其是对于分布式系统新手来说!好在市面上有大量的课程资料,对这类主题进行了详尽的讲解。以下是我最喜欢的一些资料,也是我在学习时钟和时间时所依赖的!
- 计算机时钟如何工作?,网络时间基金会
- 分布式系统中的时间,Brian Nielsen
- 时钟和时间,Behzad Bordbar
- 同步物理时钟,Srinivasan Seshan
- 分布式系统基础,Ronald LeRoi Burback
鏂囩珷鏉ユ簮锛�https://dev.to/vaidehijoshi/ticking-clocks-in-a-distributed-system-b41