NoSQL 数据库不该该放弃 Consistency

谈到 NoSQL,必定会说起一致性(Consistency),按照 CAP 定理,有些 NoSQL 数据库放弃了一致性,可是 NoSQL 放弃是必然的选择吗?web

从 1970’s,关系型数据库(RDB,Relational Database)被发明以来,关系型数据库就是构建应用的一般的选择。关系型数据库对用户提供 ACID 保证,很是方便开发者使用。从 1990’s 开始,NoSQL 系统开始出现。NoSQL 系统是一类对立于关系数据库的数据库系统,他们从架构上放弃了传统的关系型数据库的的关系模型和 SQL 的接口。数据库

与 NoSQL 系统相伴而来的 2 个词是 BASE 和 CAP,这 2 个词对分布式系统有着很是深远的影响。我相信就是在这 2 个词的影响下,不少 NoSQL 系统从架构的初始就放弃了一致性(consistency)选择了一种最终一致性(Eventual consistency)和可用性 (Availability)。虽然我很是认同 CAP 和 BASE 这 2 个词,可是我不认为在 CAP 和 BASE 的做用下,NoSQL 系统选择放弃一致性是一个必然的事情。缓存

首先来回顾一下 CAP 和 BASE 这 2 个概念的历史。这 2 个概念都是由 Eric Brewer 提出的,Brewer 目前是 Google 公司的基础设施部门(Infrastructure)的副总裁(VP,Vice President)。在 1997 年,在 SOSP(Symposium on Operating Systems Principles) 上,名为的演讲 [1] 总结了 Brewer 等人的近期工做,演讲中说他们正在工做的集群服务并无采用当时公认的具备 ACID 特性的关系型数据库做为架构,而是在架构上放弃了关系型数据库的 ACID 特性。而且为他们的这个架构选择构造了一个新的词 BASE,BASE 这个词的选择有刻意为之成分,ACID 在英语里有酸性的意思,而 BASE 有碱性的意思,很明显 BASE 是与?ACID 对立的。网络

ACID 和 BASE 分别是以下单词的首字母缩写:
ACID:Atomicity, Consistency, Isolation, Durability
BASE: Basically Available, Soft State, Eventual Consistency架构

BASE 主张放弃掉 ACID,主要是放弃 ACID 中的 Consistency,而且让系统达到基本可用(Basically Available),柔性状态(Soft State),最终一致(Eventual Consistency)。系统构建者能够不只仅选择 ACID,BASE 也称为一种选择,也就是在 ACID 和 BASE 中选择其一。本质上来说,就是在 ACID 表明的一致性 (Consistency) 和 BASE 表明的可用性(Availability)两者之间作出选择。虽然在 BASE 提出时,尚未明确说明在一致性和可用性间作出架构选择,可是已经为后面 CAP 的提出作好了伏笔。运维

到 2000 年,Brewer 在 PODC(Principles of Distributed Computing)作了名为 [2] 的演讲,演讲的主旨是阐明如何构建健壮的分布式系统。在此次演讲中,Brewer 近一步分析比较了 ACID 和 BASE,而且抽象了 ACID 和 BASE 的核心特性,也就是 ACID 的一致性(Consistency),BASE 的可用性(Availability),而且扩展了第 3 个维度,也就是网络分区(Network Partition),从而提出了CAP 猜测,这个猜测说:分布式

在分布式系统中,最多能同时知足如下 3 个属性中的 2 个:
C (Consistency), A (Availability), P (Tolerance to network Partitions)ide

根据这个猜测,会存在 3 类系统:大数据

放弃 P,系统具备 CA 特性,这类系统诸如单机数据库
放弃 A,系统具备 CP 特性,这类系统诸如分布式数据库、分布式锁
放弃 C,系统具备 AP 特性,这类系统诸如 web caching、DNS
可用性是很是重要的一个特性,特别是在互联网行业中,服务宕机对商业的影响是很是大的,因此依据 CAP 定理放弃一致性也就是天然的选择了。特别是在 Amazon 的 CTO Werner Vogels 详细介绍了 Eventually Consistent[5] 和 Amazon 的 Dynamo 系统的论文 [12] 发表后,大量追求可用性放弃一致性的 NoSQL 系统出现。云计算

到了 2002 年,GilBert 和 Lynch[3],从新定义了 CAP 这 3 个属性(从新定义的属性比 Brewer 猜测中的属性的范围小了不少),而且证实了 CAP 这 3 个属性不能同时达到,从而将 CAP 猜测变成了CAP 定理。

CAP 定理中的 3 个属性定义以下 [3,6]:
Consistency: 是指原子一致性(Atomic consistency)或者线性一致性(linearizable consistency),这是一种很是高的一致性级别,不多有系统可以达到。
Availability: 是指彻底的可用性,也就是每一个到达每一个没有宕机的节点上的读写请求都能在一个合理的时间返回一个响应。这里的关键点是每一个请求到达每一个非宕机的节点。这也是一种很是高的可用性水平,也不多有系统可以达到。
Partition Tolerant: 是指系统可以在出现网络分区的状况下,继续正确响应,即保持系统该有的特性,或者说保持一致性或者可用性。

Glibert 和 Lynch 从新定义的 CAP 定理很是严谨,可是只证实了 3 个属性不能同时具备。然而 Brewer 猜测中的 3 个属性的定义、3 选 2 的描述,3 分的分类法(AP,CP,CA3 种分类)却不是很是严谨,这也是 CAP 出现以后,不少人怀疑和挑战 CAP 的缘由。Brewer 在 2012 年从新写了一篇文章 [4],也认可最初的 CAP 表述很是使人误解。事实上,CAP 定理的适用范围是很是小的。 虽然 CAP 从出生开始就有不少问题,可是它仍然推进了 NoSQL 运动,不少系统架构者依据 CAP 定理,主动放弃了一致性,但实际上,不少时候这些系统都是不知足 CAP 定理的适用范围的。

CAP 的故事到此并未完结,2017 年,Brewer 已是 Google 公司的基础设施(Infrastructure)部门的副总裁(VP,Vice President)了,而且这时 Google 公司的第一代 Spanner 系统已经诞生 [9]。Brewer 写了一篇文章讲述了 Google 公司的 Spanner 系统 [7],而且近一步阐述了按照 CAP 定理 Spanner 是一个什么样特性的系统。在文中,Brewer 指出 Spanner 系统说是 " 实际上的 CA"(effectively CA)系统。从架构上来说,Spanner 是一个 CP 系统,也就是说当出现网络分区时,Spanner 选择的是保证数据的一致性,放弃可用性的。但实际上,Spanner 是具备很是高可用性效果的一个系统,从架构上 Spanner 没有达到 CAP 定理要求的那种彻底可用性,可是也达到很是高的可用性,因为采用多副本的设计,个别副本出现网络分区,并不影响用户能感知到的可用性。按 CAP 定理的定义,当这些个别副本出现网络分区时,这些节点是不可用的,也就是系统没有达到彻底可用性。可是此时的用户请求是能够被其余副本服务的,此时服务是可用的,也就是说用户仍然感知到 Spanner 是可用的。因此说用户感知的可用性和 CAP 定理中的可用性不是一个概念。咱们追求的应该是用户感知的可用性。

用户可感知的可用性,一般用 SLA 来表示,也就是咱们一般说的几个 9 的可用性。Brewer 在文章中也给出了 Google 关于 Spanner 系统的 SLA 的数据,从数据咱们能够看到,因为网络分区致使的服务可用的比例是比较小的,有很大一部分致使服务不可用的缘由是诸如软件 bug、配置错误、运维误操做等致使的。也就是说,即使在架构上采用了达到 CAP 定理要求的可用性,实际用户可感觉到的服务可用性,也就 SLA 也不会提升多少。这也是我从业这么多年的一个体会,系统的不稳定更多来自系统开发者的平常失误,增强代码质量,增强开发流程规范,增强生产运维规范,更能大大提升系统的可用性。因此,在架构层面,由于可用性放弃一致性每每是得不偿失的。

云计算的大潮下,不放弃一致性也是很是明智的。一个托管在云上的数据存储服务,若是你放弃了一致性选择可用性,用户是感觉不明显,由于使用者不会对架构设计采用达到的 CAP 定理的可用性而买单,用户只会为你的服务达到 SLA 买单。然而数据存储服务是否具备一致性,用户是可以很是明显的感觉到的。Amazon 公司的内部的 Dynamo[12] 在架构上是能够达到 CAP 定理中的可用性要求的,可是 Amazon 在 AWS 云上售卖的 DynamoDB 并非采用的这一架构,也许就是出于这个缘由 [10]。

那么咱们选择一致性获得的好处是什么那?不少时候,说到一致性时,都会拿金融和钱相关的例子来讲明一致性的必要性,可是我相信金融行业并不强依赖一致性 [10]。我认为一致性给我带来的是开发的方便性。Brewer 虽然提出了 BASE 概念,可是他并无详细阐述这个概念。2008 年 EBay 公司的 Dan Pritchett,写了一遍文章 [8],经过举例详细阐述了在放弃了 ACID 之后,如何采用 BASE 架构实现相同的需求,向咱们推荐了 BASE 这种架构模式。经过这篇文章,咱们我能够看到若是放弃了 ACID 而选择 BASE 的话,原本一个很是简单的功能,须要加入消息队列等手段才能让系统达到最终一致性,应用的总体架构复杂了不少。

相似于 Pritchett 文章中说明的同样,使用不具备一致性的 NoSQL 系统,你须要仔细甄别你的使用场景,判断你的使用场景是否可让你放弃一致性。即使你要使用 BASE 架构,也不是简单地采用一个具备最终一致性的 NoSQL 系统,替换掉 ACID 数据库就行了,你须要设计好各类手段,处理掉具备最终一致性的 NoSQL 系统带来的异常,让你的整个应用达到柔性状态和最终一致。BASE 中所说的最终一致和不少 NoSQL 系统所具备的最终一致有些细微的差异。这个差异简单来讲是,BASE 中所说的最终一致是保证系统状态是正确的;而不少 NoSQL 系统最终一致只保证最终一致,可是不保证这个状态是你想要的正确的状态 [11]。

最后,我的的一个观点是,若是一个 NoSQL 系统作为缓存使用,为了追求低延时,能够放弃一致性,大数据和离线计算的场景相似于这种场景,不少 NoSQL 系统是很是适用的;可是若是 NoSQL 系统做为数据库来用,那么这个 NoSQL 系统最好不要由于可用性放弃一致性,同时经过多副本技术和良好运维达到实际的高可用性,即达到实际上的 CA(effectively CA),这样能够大大下降使用者的使用负担。

因为篇幅所限,本文中关于一致性、CAP、BASE、ACID 的不少技术细节的阐述未能详尽,拟另行成文讨论。成文仓促,有错漏之处欢迎各位大神指正。


原文连接 本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索