分布式数据库原理、架构与实践
上QQ阅读APP看书,第一时间看更新

1.3 分布式系统一致性的本质

分布式系统是不稳定系统,即事件的发生及产生的结果是不可确定的。出现不可确定有两个方面的因素:一是操作/事件发生需要感知和应答;二是系统部件存在发生故障的可能,包括1.1.2节讨论的各种故障。对于分布式系统,构建者总是期望系统在预期中运行而不是充满各种不可预期的事件及结果,所以总要发明出一些东西来预防、规范分布式系统的行为和结果。

有序化是一种有效的使分布式系统具备“确定性”的手段。有序化使得系统可预期,这是逻辑上的可预期。

分布式系统的一致性问题本质上是“有序”问题,这包括两个方面:一是伴随并发操作/事件的数据异常问题可通过排序来解决,而事务处理技术是使相关数据项具备原子性和隔离性(并发事务不受其他事务影响而保持结果满足特定隔离级别的期望)并以此来确定操作/事件间的“偏序”关系,进而在事务上累积起偏序或全序关系(事务具备全序关系则表示无异常);二是分布式一致性为从系统外部确认发生在系统内的操作/事件的“偏序”或“全序”关系。因此,本节采用数学知识进一步阐述分布式一致性和事务一致性的本质。简单表述为:分布式一致性是为操作/事件定序,事务一致性是以多个操作/事件组成的事务定序。

分布式系统强调的是可用性和可靠性,这是物理上的一种有效的使分布式系统具备“确定性”的手段。怎么确保系统和服务持续可用?怎么确保系统和数据一直可靠有效?在分布式系统中这些也是重要的问题。通常的解决方式是,基于多副本技术来提供可靠性和可用性(多副本技术参见第3章)。

1.3.1 偏序与全序

在一个多进程或分布式架构的系统中,需要知晓事件和消息传递时的顺序关系,这涉及偏序和全序的概念。

偏序和全序是数学中的公理集合论中的概念。

偏序是指集合内在某种关系下只有部分元素之间是可以进行比较的。例如,复数集中并不是所有的数都可以比较大小,能比较大小的只是其中的一部分,所以“大小”就是复数集的一个偏序关系。其定义为:

R是集合A上的一个二元关系,若R满足如下条件,则称RA上的偏序关系。

Ⅰ自反性,即对任意xA,有xRx

Ⅱ反对称性(即反对称关系),即对任意xyA,若xRy,且yRx,则x=y

Ⅲ传递性,即对任意xyzA,若xRy,且yRz,则xRz

全序是指集合内任何一对元素在某个关系下都是相互可比较的。例如,英语单词在字典中是全序的。其定义为:

设集合X上有一个全序关系,如果我们把这种关系用≤表示(不是数学中的小于等于),则下列陈述对于X中的所有abc成立:

Ⅰ如果abba,则a=b(反对称性);

Ⅱ如果abbc,则ac(传递性);

abba(完全性)。

因为完全性本身也包括了自反性,所以全序关系必是偏序关系。但偏序关系在满足反对称性和传递性的条件下,不满足完全性。例如,自然数集中的整除关系为偏序关系但不是全序关系,因为不是任意两个自然数都能相互除尽。

分布式系统中的各种一致性,其本质就是在讨论多种不同的顺序关系(第2章将对此深入讨论)。分布式一致性可分为两种情况:一是结果一致性,二是次序一致性。偏序和全序表达的就是次序一致性,所以本段第一句话可修正为“分布式系统中的次序一致性,其本质就是在讨论多种不同的顺序关系”。并发事件怎么构成偏序或全序,是构建分布式系统时面临的挑战之一。

1.3.2 有序与并发

我们所处的世界/宇宙,是一个高度并发的分布式系统。在这个系统里,相关的、不相关的,一同向前发展。相关的存在交互,需要“有序化”来帮助我们理解/规范它们之间的关系,不相关的则一直“并发”向前。其中,衡量“相关关系”的一个逻辑是“序”,我们可将“时间”视为尺子对序进行度量,这个过程名词化后就是“一致性”。

在计算机范围内,首先提出数据一致性问题的是参考文献[82,83]。数据一致性随着对多处理器系统和并行计算模式的兴起与发展的研究而被提出。这里说的多处理器系统有如下两类。

  • 紧耦合多处理器系统(tightly coupled multi-processor system):多个处理器访问同一个集中式的共享内存。
  • 松耦合多处理器系统(loosely coupled multi-processor system):每个处理器都拥有各自的(本地)内存,并可以远程访问其他处理器的内存。

无论是在紧耦合还是松耦合的多处理器系统中,多个处理器以并发访问同一地址空间的方式进行通信,这使得因数据操作“相关”而带来数据一致性问题。这样的问题就是本书重点探讨的问题,即1.1节探讨的一致性问题。

在分布式系统中,影响一致性的有两个维度:一个是时间维度,另外一个是事件顺序维度。

时间维度是指时间系统对分布式系统的影响,这是一种直接的影响。这种影响主要体现在时延上。时延是指多个节点之间的时间值不同。而分布式系统需要一个统一的标尺,以衡量各个节点上发生的操作,这个标尺天然就是时间。为了同步多个节点之间的时间,需要用全局时钟校对每一个节点的时钟,以使分布式系统内的所有节点在时间层面保持同步。但是,同步并不是就意味着每个节点之间的时间值完全一样,而是可以存在一定的误差。这个误差值越小,就说明该时钟同步系统越精确。例如Google的Truetime系统误差在7ms之内,而通过NTP[1]校对的分布式系统误差在100ms到250ms之间。

事件顺序维度是指事件的发生有其前后次序,但是事件发生后,观察者观察到的结果可能和原来的顺序相反。其实,事件的顺序也暗含“用时间做单调递增的标尺来考量事件之间的逻辑先后顺序”之意,即事件的顺序和时间紧密相关。而对于事件顺序的感知,是从一个观察者的角度进行的。这表明,分布式系统的一致性实质是观察者对事件逻辑顺序的感知,但这种感知受到了分布式系统中单个节点基于本节点时间系统对事件发生的时间进行赋值的影响(时间的本意是单调有序的)

另外,对于分布式数据库来说,如果是基于封锁技术的,则不需要全局时间。而依据全局时间校对各个节点的时间并使之同步,意味着数据库会使用基于时间戳排序的并发访问控制技术来描述在不同节点上发生的并发操作之间的先后关系。如果分布式数据库要使用MVCC技术,就会因MVCC技术本身不考虑事务的顺序,而需要配合封锁技术或时间戳排序技术才能使用。Google的Percolator采用了逻辑时间的方式(单调递增的全局事务号)来规避各个节点校对、同步时间的问题,因此如果采用类似Percolator的事务处理机制,则排序并发事务之间的提交次序可以使用基于时间戳的并发访问控制技术实现。第三篇会对Spanner、Percolator、CockroachDB等分布式数据库的事务处理机制进行深入分析。

如上所述,不管是应用封锁技术还是基于时间戳排序,都是在试图把相关的操作/事件有序化,让相关和不相关的操作/事件并发执行。


[1]参见https://en.wikipedia.org/wiki/Network_Time_Protocol