一致性模型一句话总结

最近在一次分布式系统的线上交流中,发现居然有那么多种不同的一致性模型,而且因为种类太多,大家理解上也有很多不同,看了一些资料,虽然很多讲的很好,但是过于复杂或者书面,难以理解,所以在这里尝试着为每一个模型做一句话总结,希望可以帮助大家理解。如果我的理解有误,也请大家指正~


1. 啥?啥一致性?

一致性虽然是我们非常常用的一个词,但是非常不幸的是,这个词有太多的含义,在使用的非常容易混淆。所以在讨论一致性之前,我们需要先来看一下一致性的定义:

首先是我们常说的Consistency。这个词经常在两个地方出现:分布式系统的CAP和数据库的ACID。虽然其中“C”都叫一致性(Consistency),但是其含义却截然不同:

  • ACID中的一致性:这里主要说的是一种数据上的约束,比如主键是否唯一,或者外键关系是否保持等等
  • CAP中的一致性:这里主要说的是不同节点之间数据的同步状态,是不是能让客户端请求处理看上去像访问一个单体系统(Monolith)一样。

然后是Coherence。这个词虽然也翻译成一致性,但是它和上面的一致性截然不同。Coherence指的是多实体或者多层级的数据之间是否一致,比如:缓存一致性(Cache Coherence,缓存中的内容是否和原始内容保持一致)。而Consistency指的是一个单实体本身是否一致,比如上面提到的同一个数据库里的外键关系或者同一个服务不同节点之间的同步状态。


2. 强一致模型(Strict Serializable)

分布式系统中,我们说一致性的最高等级叫强一致模型(Strict serialiable或者Strong one-copy serialiability)。这个模型其实需要满足两个条件,而这也是我们非常容易混淆的两个条件:可串行性(Serializability)线性一致性(Linearizability),这也是两个分支领域的最高一致性等级:可串行化(Serializable)可线性化(Linearizable)

  • 可串行化(Serializable),又叫事务一致性,是一种事务隔离的级别,也就是ACID中的I(Isolation),它保证事务在并发执行时的执行顺序对数据的一致性没有影响。可串行化并不保证数据读写的时间顺序,比如数据库,执行SQL语句时,我们允许数据库对其子操作的执行顺序进行任意的重排,只要最后要做的事情保持不变即可。
  • 可线性化(Linearizable),又叫数据一致性,它表示某个对象在写操作之后是否能马上读到这个最新的值,比如,我们更新了twitter上的昵称,那刷新页面之后是不是能不能马上看到这个变化,还是说在一段时间内,刷新页面可能还会看到老的昵称?

为了方便大家捋清楚这两个大领域和各种一致性模型关系,这里从JEPSEN的网站上找来了一个总结图
Consistency model family tree


3. 可线性化 / 数据一致性(Linearizable)

数据一致性分为两类:强一致性和弱一致性。简单的说,只有线性一致性属于强一致性,其他的都属于弱一致性。所谓强一致性,即数据的复制是同步的,弱一致性,即数据的复制是异步的,所以我们可能会看见部分数据不一致的情况。

模型
解释
举例
线性一致性
Linearizability /
Linear Consistency
经典的强一致性,每一个操作都会严格的按照真实时间序线性顺序发生 给某个数据加个锁
顺序一致性
Sequential Consistency
允许延迟,但是数据的生效必须严格保持线性 FIFO队列处理
因果一致性
Casual Consistency
对数据的操作有逻辑关系(事件B仅在条件A满足时才能发生),则数据的变化必须按顺序生效,但是不相关的数据之间可以乱序 帖子管理,帖子的创建必须发生在回复帖子之前
管道一致性
PRAM/FIFO Consistency
某一个使用者完成的写操作可以被其他所有的使用者按照顺序的感知到,而从不同使用者中来的写操作则无需保证顺序,就像一个一个的管道一样 PubSub
最终一致性
Eventual consistency
如果没有新的更新提交,最终所有的访问都将获得最后的更新,但是它并不保证所有修改导致的中间状态都能被观察到 提交了修改,但是需要等待数据同步,异地灾备等等

而其中,最终一致性又能被继续细分:

模型
解释
举例
读不旧于写一致性
RYW (Read-your-writes) Consistency
每个使用者读取到的数据,一定不老于自己的上一次写 更新系统时生成时间戳,避免读取到此时间戳之前的缓存;数据库主从分离,拥有写权限的人,比如所有者,永远读写主库,其他人读从库
单调读一致性
Monotonic-read (MR) Consistency
如果一个用户从系统中读取出一个数据项的某个值后,那么系统对于该用户后续的所有数据访问都会返回更旧的值 从从数据库读取数据
单调写一致性
Monotonic-write (MW) Consistency
来自同一个用户的写操作,会被顺序地执行 允许合并操作的写队列
写不旧于读一致性
Writes-follow-reads (WFR) Consistency
来自同一个用户的写操作,一定不会作用于比其读出来的数据更早版本的数据 还是帖子管理,如果看不见帖子,则没有办法回复帖子,但是只要能回复帖子,就一定需要保证帖子被创建

4. 可串行化 / 事务一致性(Serializable)

同样的,可串行化也分为强一致性和弱一致性,其中我们最常说的强一致性指的就是可串行化中的最高等级:可串行性。其他的等级都有不同程度的弱化。

ANSI对SQL的隔离等级做了很好的定义,由弱至强依次如下:

模型
解释
未提交读
Read Uncommitted (RU)
最低等级的一致性保证,在事务之中允许读取未提交的数据(Dirty Read)
已提交读
Read Committed (RC)
在事务中,读取到的数据一定是提交了的,但是不保证这些数据会不会在重复读时发生变化
可重复读
Repeatable Read (RR)
在已提交读的基础上,还保证在一个事务中,读取过的数据在重复读中保持不变,但是同样的查询可能会查到新的数据(Phantom Read)
可串行性
Serializability (S) /
Serializable consistency
最高等级的一致性保证,提供和SI同样的保证,但是一般是使用锁而不是快照来实现的,不会在合并修改时发生的错误

除了标准等级以外,这里还有一些额外的等级,有些是论文里面的,有些是数据库厂商自己定义的:

模型
出处 / 数据库
解释
Item Cut Isolation (I-CI) HAT 一种可重复读的弱化形式,在已提交读的基础上,同一个事务内,对相同的数据永远返回相同的结果,一般是利用快照来实现
Predicate Cut Isolation (P-CI) HAT 一种可重复读的弱化形式,在已提交读的基础上,同一个事务内,对相同的where clause永远返回相同的结果,一般是利用快照实现
单调原子视图
Monotonic Atomic View (MAV)
HAT 在已提交读的基础上,添加一个额外的保证,如果某个事务读取的数据被其他的事务修改了,那么这个事务的所有修改都应该能被当前事务发现。MAV只负责数据生效的同步,但是它并不保证数据可重复读,如果读取的数据在事务进行中被多次提交,那么多次查询可能返回不同的结果
稳定游标
Cursor Stability (CS)
[IBM DB2][IBMDb2CS] 在已提交读的基础上,如果事务内,某个数据行存在游标(Cursor)指向它,则会对该数据行加锁(Row Lock),保证其数据不变,但是重复查询会看到其他数据的变化或者读取到新的数据
稳定读
Consistent Read (CR)
[Oracle][OracleCR] 一种可重复读的实现方法,在已提交读的基础上,通过对需要读取而正好被并发事务修改而且未提交的数据创建一份快照,保证其在事务内的重复读保持不变
快照
Snapshot Isolation (SI)
[SQL Server][MsSqlServerIsolations] 在可重复读的基础上,保证重复读不会查询到新的数据,但是其内部实现不是通过加锁完成的,而是通过抓取快照

这里可以看到好几个基于快照的隔离实现,比如SI,P-CI和I-CI,他们的等级都会要比相对应的非快照实现要低(S和RR),这个原因是由于并发事务可以对多个快照中的相同数据进行不同的修改,所以会导致合并数据修改结果时,发生错误或者时意料之外的情况

这里还有一个很有意思的事情是,虽然很多数据库都号称他们实现了100% ACID,但是其实事实上并没有,这里Peter Bailis对市面上的数据库做了一个总结如下,Github上还有一个非常好的数据库隔离等级的测试项目Hermitage

Database Default Isolation Maximum Isolation
Actian Ingres 10.0/10S S S
Aerospike RC RC
Akiban Persistit SI SI
Clustrix CLX 4100 RR ?
Greenplum 4.1 RC S
IBM DB2 10 for z/OS CS S
IBM Informix 11.50 Depends RR
MySQL 5.6 RR S
MemSQL 1b RC RC
MS SQL Server 2012 RC S
NuoDB CR CR
Oracle 11g RC SI
Oracle Berkeley DB S S
Oracle Berkeley DB JE RR S
Postgres 9.2.2 RC S
SAP HANA RC SI
ScaleDB 1.02 RC RC
VoltDB S S

5. 相关资料

[OracleCR]: https://datacadamia.com/db/oracle/consistent_gets)
[IBMDb2CS]: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/db2/rbafzcursorstability.htm
[MsSqlServerIsolations]: https://docs.microsoft.com/en-us/sql/connect/jdbc/understanding-isolation-levels

原创文章,转载请标明出处:Soul Orbit
本文链接地址:一致性模型一句话总结