在我的其他几篇文章里,已经多次提到线性一致性(Linearizability),那么到底线性一致性(Linearizability)是什么?线性一致性(Linearizability)有什么用处?
虽然,我们最常提到Linearizability是在讨论分布式系统的时候,但其实Linearizability是一个并发编程(concurrent programming)领域的概念。
线性一致性又叫做原子一致性。在并发编程中,如果一个操作对于系统的其他部分是不可中断的,那这个操作就可以称之为原子的,线性的,不可分割的。那这个操作就可以称之为具有线性一致性的特性。
原子操作具有”要么成功要么失败”的特性,就是说要么这个操作成功修改系统的状态,要么不会有任何作用。
操作系统的多线程编程就是一种并发编程。在做多线程编程时,并发控制是我们最需要考虑的一个事情,我们常常用各种锁来保护(shared-data)共享数据。那么操作系统是如何实现的这些锁那?在硬件层面,硬件会提供一些具有线性一致性的指令,比如atomic read-write,atomic swap,test-and-set,操作系统基于这些指令建立mutual exclusion、 semaphores 等锁结构。
在分布式领域中,我们也会说线性一致性,例如Zookeeper是线性一致性的,再比如分布式领域著名的CAP定理中的C,也是指线性一致性。(关于这一点请参看<从Paxos不违反CAP来解释什么是CAP定理>)虽然我们在讨论分布式系统的线性一致性,但其实我们是将一个分布式系统看成一个整体,分布式系统的多个客户端同时访问操作这个分布式系统。这种场景和在多线程编程中,多个线程访问操作同一个内存是类似的。所以这也是一个并发编程的场景。类似于多线程编程中,我们需要锁机制来控制多个线程的并发访问,在分布式编程中也需要控制多个进程的并发访问,也需要一种锁机制,那么就要用Zookeeper这样就有线性一致性的系统来充当协调者(coordinator),来实现分布式锁。
从多线程编程和分布式编程中,我们可以看出,线性一致性是实现并发控制的原语(Primitive),在这个原语的基础上可以实现各种锁机制来控制并发访问。
所以说,线性一致性(Linearizability)是并发编程中(包括多线程编程和分布式编程)并发控制的基础。
如果你的系统具有线性一致性,那么你的系统可以用来做分布式锁服务,从系统本身来讲,具有很好的并发控制能力。
另外,Linearizability可以得出客户端视角的一个特性,只要一个value被写入,那么后续的client做read操作时,一定能够读到这个新值。(在< Tunable Consistency不能让Cassandra成为CP系统>这边文章讨论中就用到了这个特性)