2017 年在饿了么做异地多活建设之时,我的团队承担了 Zookeeper 的异地多活改造。
在此期间,我听到了关于 Zookeeper 一致性的两种不同说法:
Zookeeper 是最终一致性的,由于多副本,以及保证大多数成功的 Zab 协议,当一个客户端进程写入一个新值,另一个客户端进程不能保证马上就会读到,但能保证最终会读到这个值。
Zookeeper 的 Zab 协议类似于 Paxos 协议,并且提供了强一致性。
每当听到这两种说法,我都想纠正一下。Zookeeper 是顺序一致性(Sequential Consistency)的,但解释起来比较复杂,下面和大家一起讨论下我的看法。
什么是 Sequetial Consistency
从 Zookeeper 的文档中我们可以看到,里面明确写出它的一致性是 Sequential Consistency。
那么,什么是 Sequential Consistency 呢?
Sequential Consistency 是 Lamport 在 1979 年首次提出的。论文中定义,当满足下面这个条件时就是 Sequential Consistency:
the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program.
这段英文定义很晦涩,这是 Lamport 大神的一贯风格,严谨但晦涩,Paxos 协议也是如此。
我第一次看到时的感觉是:“这是什么鬼?”为啥每个英文单词我都认识,但就是不知道他在说什么?
我们先看看这篇论文的标题和定义中出现的一个关键词,来说明一下 Sequential Consistency 的应用范围。
论文的标题和定义中包含“multiprocessor”这个词,multiprocessor 是多核处理器的意思。
从这个关键字来看,Sequential Consistency 是用来定义多核处理器和跑在多核处理器上的程序的一个特性。
Lamport 这篇论文的标题可以翻译成:“如何让具有多核处理器的计算机正确执行多进程程序”。
也就是说如果一个多核处理器具有 Sequential Consistency 的特性,这个多核处理器就可以正确运行,后面我会解释这个正确运行是什么意思(也就是本文后面讲到的 Sequential Consistency 的作用)。
从这个标题我们还可以看出,Sequential Consistency 应该是个并发编程(Concurrent Programming)领域的概念。
但我们现在常常在分布式系统领域讨论 Sequential Consistency,比如本文主要讨论的 Zookeeper(Zookeeper 很明显是一个分布式系统)的一致性。
实际上,多核处理器上运行的多个程序,其实也是一种分布式系统(Lamport在他的这篇 Time,Clocks,and the Ordering of Events in a Distributed System 分布式系统的开山之作中也阐述了这个观点)。
所以虽然 Sequential Consistency 最早在并发编程中提出,但是它可以应用在分布式系统中,比如本文讨论的 Zookeeper 这种分布式存储系统。
另外一个比较重要的 Linearizability(线性一致性),也是在并发编程中最早提出的,目前也被广泛应用在分布式系统领域中。
接下来我们尝试翻译一下上文那段晦涩的定义,做这段翻译让我找到了上学时做阅读理解的感觉。
我先不直接翻译,因为就算我把它翻译成中文,估计很多人还是会有“为啥每个中文字我都懂,还是不知道在说什么”的感觉。
首先,我来解释一下个别的词。首先,“any execution”是什么意思?你有多个程序(Program)在多核处理器上运行,例如你有两个程序。
第一个程序叫 P1,它的代码如下:
P1_write(x);
P1_read(y);
第二个程序叫 P2,代码如下:
P2_write(u);
P2_read(v);