EagleBear2002 的博客

这里必须根绝一切犹豫,这里任何怯懦都无济于事

NoSQL-一致性与 CAP 模型

一致性是高可用的必备条件

分布式数据库的节点并不总是处于活动状态且相互能够通信的。系统高可用性是分布式数据库一个极其重要的特性。

为了使系统能够高度可用,系统需要被设计成允许一个或多个节点的崩溃或不可访问。

高可用必须要尽可能满足业务连续性数据一致性这两个指标。第三个因素网络分区会对可用性产生影响。

CAP 理论与注意事项

可用性是用于衡量系统能够成功处理每个请求并做出相应的能力。

  1. 希望每个操作都保持一致性(原子一致或线性一致性)
  2. 希望在容忍网络分区的同时,实现一致性和可用性

可用性要求任何无故障的节点都可以提供服务;一致性要求结果需要线性一致

CAP 理论认为,异步系统无法满足可用性要求,并且在存在网络分区的情况下,无法实现同时保证可用性和(线性)一致性的系统。

CP 系统:一致且容忍分区的系统,更倾向于减少服务时间,而不是将不一致的数据提供出去。一些面向交易场景构建的 NewSQL 数据库倾向于这种策略。场景实现思路是引入共识算法,需要大多数节点参与进来,才能保证一致性。

AP 系统:可用且容忍分区的系统,放宽了对一致性的要求,并允许在请求期间提供可能不一致的值。一般是列示存储,NoSQL 数据库会倾向于 AP,如 Apache Cassandra,会通过不同级别的一致性模式调整来提供高一致性方案。只要一个副本就能启动,数据库会始终接受写入和读取服务。

CA 系统不存在。

CAP 理论讨论的是网络分区,而不是节点崩溃或任何其他类型的故障。即使所有节点都在运行,也可能存在不一致性问题,因为存在连接性问题。

一致性模型

一致性模型是分布式系统的经典内容。

滞后性:数据改变的时刻与其副本接收到数据的时刻之间的差异

顺序性:各种操作在系统所有副本上执行的顺序状态

为了推理操作顺序并指出真正的结果,必须定义一致性模型来保障顺序性。保障是将一致性模型是为用户与数据库之间的一种约定。由强到弱介绍一致性:

严格一致性

严格的一致性类似于不存在复制过程。任何节点的任何写入都可立即用于所有节点的后续读取。

该模型现实当中无法满足。分布式数据库不可能一瞬间同步所有变化。

线性一致性

线性一致性是最严格的且可实现的单对象但操作一致性模型。需要满足新写入的数据一旦被读取出来,那么所有后续的操作应该能读到这个数据。

  • 需要有全局时钟,来实现所谓的“最近”。因为没有全局一致的时间,两个独立进程没有相同的“最近”概念。
  • 任何一次读取都能读到这个“最近”的值

下图是一个线性一致性的例子,集合当中的元素是该操作可能返回的值。

线性一致性代价高昂,甚至 CPU 都不会使用线性一致性。

常见误区:使用一致性算法可以实现线性一致,如 Paxos 和 Raft 等。

Raft 算法值保证了复制 log,未保证如何将 log 写入状态机。

顺序一致性

顺序一致性放弃了全局时钟的约束,改为分布式逻辑时钟实现。指所有进程以相同的顺序看到所有的修改。

可以使用一致性算法保证顺序一致性。

因果一致性

仅要求有因果关系的操作顺序是一致的,没有因果关系的操作顺序是随机的。

  • 本地顺序:本进程中,事务执行顺序即为本地因果顺序
  • 异地顺序:如果读操作返回的是写操作的值,那么该写操作在顺序上一定在读操作之前
  • 和时钟向量一样里面定义的一样,如果 \(a > b \wedge b > c \Rightarrow a > c\)

因果相关的写操作,加入逻辑时钟:

事务隔离级别与一致性模型

ACID 和 CAP 中的 C 都是一致性。后者指的是线性一致性。

事务隔离是描述并行事务之间的行为,而一致性是描述非并行事务之间的行为。