写点什么

NoSQL 数据库不应该放弃 Consistency

  • 2019-05-09
  • 本文字数:5667 字

    阅读完需:约 19 分钟

NoSQL数据库不应该放弃Consistency

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


从 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)


根据这个猜想,会存在 3 类系统:


  1. 放弃 P,系统具有 CA 特性,这类系统诸如单机数据库

  2. 放弃 A,系统具有 CP 特性,这类系统诸如分布式数据库、分布式锁

  3. 放弃 C,系统具有 AP 特性,这类系统诸如 web caching、DNS


可用性是非常重要的一个特性,特别是在互联网行业中,服务宕机对商业的影响是非常大的,所以依据 CAP 定理放弃一致性也就是自然的选择了。特别是在 Amazon 的 CTO Werner Vogels 详细介绍了 Eventually Consistent[5]和 Amazon 的 Dynamo 系统的论文[12]发表后,大量追求可用性放弃一致性的 NoSQL 系统出现。


到了 2002 年,GilBert 和 Lynch[3],重新定义了 C\A\P 这 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 的很多技术细节的阐述未能详尽,拟另行成文讨论。成文仓促,有错漏之处欢迎各位大神指正。


作者简介:陈东明,饿了么北京技术中心架构组负责人,负责饿了么的产品线架构设计以及饿了么基础架构研发工作。曾任百度架构师,负责百度即时通讯产品的架构设计。具有丰富的大规模系统构建和基础架构的研发经验,善于复杂业务需求下的大并发、分布式系统设计和持续优化。个人微信公众号 dongming_cdm。


1.Cluster-Based Scalable Network Services, A. Fox et al., 1997.


2.Towards Robust Distributed Systems, E. Brewer, 2000.


3.Brewer’s conjecture and the feasibility of consistent, available, partition-tolerant web services, Seth Gilbert,  Nancy Lynch, 2002


4.CAP twelve years later: How the “rules” have changed, Eric Brewer, 2012


5.Eventually Consistent - Revisited, Werner Vogels, 2008


6.Understanding the CAP Theorem, Akhil Mehra, https://dzone.com/articles/understanding-the-cap-theorem


7.Spanner, TrueTime & The CAP Theorem, Eric Brewer, 2017,https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/45855.pdf


8.Base: An Acid Alternative,Dan Pritchett, https://queue.acm.org/detail.cfm?id=1394128


9.Spanner: Google’s Globally-Distributed Database,2012


10.Designing Data-Intensive Applications, Martin Kleppmann


11.Jepsen: Cassandra,Kyle Kingsbury,https://aphyr.com/posts/294-jepsen-cassandra


12.Dynamo: Amazon’s Highly Available Key-value Store, Giuseppe DeCandia et al., 2007


2019-05-09 12:066204

评论

发布
暂无评论
发现更多内容

板边器件距离不够,导致元器件无法焊接,怎么办?

华秋电子

中国半导体市场份额进一步提升,2023年将迎全新发展良机

华秋电子

阿里P8裸辞真实心路历程,他底气来源于Java高阶面试合集

Java你猿哥

Java Spring Boot ssm 面经 八股文

内部开发者门户是什么?

SEAL安全

微服务 企业号 3 月 PK 榜 内部开发者门户 信息碎片化

【干货】常见库存设计方案-各种方案对比总有一个适合你

Java你猿哥

Java 架构 微服务 系统设计 后端

低代码四大典型使用场景,你都知道吗?

飞算JavaAI开发助手

索信达再度打造智能营销标杆案例,这次是头部券商!

索信达控股

MybatisX整合Spring Boot,真香!

Java你猿哥

Java Spring Boot 后端 mybatis ssm

"鸿蒙生态专家面对面"三月专场等你前来!

HarmonyOS开发者

优秀软件工程师必备的五大技能,快看你还差什么?

飞算JavaAI开发助手

【微电平台】-高并发实战经验-奇葩问题解决之旅

京东科技开发者

架构 服务端 js 平台

测试的底层逻辑

京东科技开发者

Java 测试 代码 企业号 3 月 PK 榜

深圳.NET线下技术沙龙倒计时一天

MASA技术团队

.net MASA

基于 RocketMQ Connect 构建数据流转处理平台

Apache RocketMQ

前端进阶:在 Web 中使用 C++,我让学妹另眼相看 | 技术分享

LigaAI

c++ 程序人生 前端 webassembly 企业号 3 月 PK 榜

openGemini正式加入openEuler SIG-DB ,携手开展全方面技术创新

openEuler

数据库 Linux 开源 操作系统 openEuler

瞄准2023教育春招,百度营销多措并举,推出创新型行业营销解决方案

Geek_2d6073

如何快速理解网络IO模型

Dinfan

Netty 事件循环 IO模型 Reactor多线程 网络io模型

PyTorch深度学习实战 | 基于ResNet的人脸关键点检测

TiAmo

深度学习 人脸识别 PyTorch

聊聊「订单」业务的设计与实现

Java 架构 订单管理 订单系统 订单

Nacos心跳机制实现快速上下线

做梦都在改BUG

Java Spring Cloud nacos 心跳机制

Spring Boot中如何优雅地实现异步调用?

JAVA旭阳

Java springboot

vivo 短视频用户访问体验优化实践

vivo互联网技术

CDN HTTP 优化 DNS 实践

cortex ingester 基于 hash ring 进行 token 管理

jupiter

Prometheus 一致性hash Cortex Mimir

官宣:OpenDAL 成功进入 Apache 孵化器

Databend

windows 系统下 workerman 在同一个运行窗口中开启多个 websocket 服务

江户川码农

windows 经验分享 websocket workerman 多服务

Matlab常用图像处理命令108例(七)

timerring

图像处理

使用 Athena (Presto) 分析本地 Oracle 数据库导出的数据

亚马逊云科技 (Amazon Web Services)

100Wqps短链系统,怎么设计?

小小怪下士

Java 程序员 后端 QPS

视频下载软件:MediaHuman YouTube Downloader 中文版

真大的脸盆

Mac 视频下载 Mac 软件 下载视频 视频下载工具

硬核!阿里大佬都在内卷的SpringBoot从入门到实战笔记

程序知音

Java 编程语言 springboot Java进阶 后端技术

NoSQL数据库不应该放弃Consistency_数据库_陈东明_InfoQ精选文章