与数据库事务一致性的差异
数据库事务的ACID的中也有一个一致性(consistency),但彼一致性非此一致性。ACID中的一致性是指,数据库的事务的执行,或者说事务观察到的数据,总是要满足某些全局的 一致性 约束条件,如唯一性约束,外键约束等。这个概念和数据库的数据是否多副本没关系。而本文的一致性在多副本的语境下才有意义。所以,数据库事务的一致性,是指数据项之间总是满足某些约束条件,或者说整个数据库在满足约束条件的意义上是 正确 的。
客户端视角一致性模型
在多副本的存储系统中,无论采用什么样的多副本同步协议,为了保证多个副本能够一致,本质上都要求做到:
- 同一份数据的所有副本,都能够接收到全部写操作(无论需要花费多久时间)
- 所有副本要以某种确定顺序执行这些写操作
客户视角的一致性模型定义了下面4种不同的保证。
- 单调读。如果一个客户端读到了数据的某个版本n,那么之后它读到的版本必须大于等于n。
- 读自己所写。如果一个客户端写了某个数据的版本n,那么它之后的读操作必须读到大于等于版本n的数据。
- 单调写。单调写保证同一个客户端的两个不同写操作,在所有副本上都以他们到达存储系统的相同的顺序执行。单调写可以避免写操作被丢失。
- 读后写。读后写一致性,保证一个客户端读到版本n数据后(可能是其他客户端写入的),随后的写操作必须要在版本号大于等于n的副本上执行。
CosmosDB 的一致性级别
Azure Cosmos DB2是一个支持多地部署的分布式NoSQL数据库服务。它提供了丰富的可配置的一致性级别。以下五种一致性级别,从前向后可以提供更低的读写延迟,更高的可用性,更好的读扩展性。
1. 强一致性
- 保证读操作总是可以读到最新版本的数据(即可线性化)
- 写操作需要同步到多数派副本后才能成功提交。读操作需要多数派副本应答后才返回给客户端。读操作不会看到未提交的或者部分写操作的结果,并且总是可以读到最近的写操作的结果。
- 保证了全局的(会话间)单调读,读自己所写,单调写,读后写
- 读操作的代价比其他一致性级别都要高,读延迟最高
2.有界旧一致性(bounded staleness)
- 保证读到的数据最多和最新版本差K个版本
- 通过维护一个滑动窗口,在窗口之外,有界旧一致性保证了操作的全局序。此外,在一个地域内,保证了单调读。
3.会话一致性
- 在一个会话内保证单调读,单调写,和读自己所写,会话之间不保证
- 会话一致性能够提供把读写操作的版本信息维护在客户端会话中,在多个副本之间传递
- 会话一致性的读写延迟都很低
4.前缀一致性
- 前缀一致保证,在没有更多写操作的情况下,所有的副本最终会一致
- 前缀一致保证,读操作不会看到乱序的写操作。例如,写操作执行的顺序是`A, B, C`,那么一个客户端只能看到`A`, `A, B`, 或者`A, B, C`,不会读到`A, C`,或者`B, A, C`等。
- 在每个会话内保证了单调读
5.最终一致性
- 最终一致性保证,在没有更多写操作的情况下,所有的副本最终会一致
- 最终一致性是很弱的一致性保证,客户端可以读到比之前发生的读更旧的数据
- 最终一致性可以提供最低的读写延迟和最高的可用性,因为它可以选择读取任意一个副本
Cosmos DB的文档中提到了一个有趣的数字。大约有73%的用户使用会话一致性级别,有20%的用户使用有界旧一致性级别。
Cassandra的一致性级别
Cassandra 是一个使用多数派协议的NoSQL存储系统,通过控制读写操作访问的副本数和副本的位置,可以实现不同的一致性级别。注意,作为NoSQL系统,Cassandra只提供单行操作的原子性,多行操作不是原子的。下面的读写操作,都是指单行操作。
OceanBase的一致性级别
OceanBase使用Multi-Paxos分布式共识算法在多个数据副本之间同步事务提交日志,每个修改事务,要在多数派副本应答以后才认为提交成功。多个副本之间,通过自主投票的机制,选出其中一个副本为主副本(leader),它负责所有修改语句的执行,特别的,达成多数派的事务提交日志要求包含主副本自己。在通常情况下,数据库需要保证强一致性语义(和单机数据库类比),我们的做法是,读写语句都在主副本上执行。当主副本宕机的时候,其余的多数派副本会选出新的主副本。此时,已经完成的每一个事务一定有至少一个副本记录了提交日志的。新的主副本通过和其他副本的通信可以获得所有已提交事务的日志,进而完成恢复,恢复以后继续提供服务。通过这种机制,OceanBase可以保证在少数派宕机的情况下不会丢失任何数据,而强一致性读写服务的宕机恢复时间小于一分钟。




