Jamzy Wang

life is a struggle,be willing to do,be happy to bear~~~

NoSQL中的CAP、BASE和最终一致性

原创声明:本作品采用知识共享署名-非商业性使用 3.0 版本许可协议进行许可,欢迎转载,演绎,但是必须保留本文的署名(包含链接),且不得用于商业目的。

CAP,BASE 和最终一致性是 NoSQL数据库存在的三大基石。本文将分析整理这三大基石。

CAP

在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer’s theorem),这个定理起源于University of California, Berkeley的计算机科学家Eric Brewer在2000年的分布式计算原则研讨会(Symposium on Principles of Distributed Computing(PODC))上提出的一个猜想。在2002年,MIT的Seth Gilbert和Nancy Lynch发表了布鲁尔猜想的证明,使之成为一个定理。

CAP定理指出,对于一个分布式计算系统来说,不可能同时满足以下三点,最多只能满足其中两点:

  • 一致性(Consistency)
  • 可用性(Availability)
  • 容忍网络分区(Partition tolerance)

此处输入图片的描述

一致性(Consistency)

对于分布式的存储系统,一个数据往往会存在多份。简单的说,一致性会让客户对数据的修改操作(增/删/改)要么在所有的数据副本全部成功,要么全部失败。即,修改操作对于一份数据的所有副本而言,是原子(Atomic)的操作。如果一个存储系统可以保证一致性,那么则客户读写的数据完全可以保证是最新的。不会发生两个不同的客户端在不同的存储结点中读取到不同副本的情况。

可用性(Availability)

可用性很简单,顾名思义,就是指在客户端想要访问数据的时候,可以得到响应。但是注意,系统可用(Available)并不代表存储系统所有结点提供的数据是一致的。比如客户端想要读取文章评论,存储系统可以返回客户端数据,但是评论缺少最新的一条。这种情况,仍然说系统是可用的。往往会对不同的应用设定一个最长响应时间,超过这个响应时间的服务仍然称之为不可用的。

分区容忍性(PartitionTolerance)

如果存储系统只运行在一个结点上,要么系统整个崩溃,要么全部运行良好。一旦针对同一服务的存储系统分布到了多个结点后,整个存储系统就存在分区的可能性。比如,两个存储结点之间联通的网络断开(无论长时间或者短暂的),就形成了分区。对当前的互联网公司(例如Google)来说,为了提高服务质量,同一份数据放置在不同城市乃至不同国家是非常正常的。因此结点之间形成分区也很正常。

理解CAP理论的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。

此处输入图片的描述

如果要满足Availability和Consistency,那么,为了保证可用,数据必须要有Replica。这样,系统显然无法容忍Partition。当同一数据的两个副本(Replica)分配到了两个无法通信的Partition上时,显然会返回错误的数据。 如果满足Availability和Partition Tolerance的情况。满足可用,就说明数据必须要在不同结点中有replica。然而还必须保证在产生Partition的时候仍然操作可以完成。那么,必然操作无法保证一致性。

因此在设计一个分布式存储系统时,不得不在三个特性中选择放弃一个。如果关注一致性,那么就需要处理因为系统不可用而导致的写操作失败的情况,而如果关注的是可用性,那么应该知道系统的read操作可能不能精确的读取到write操作写入的最新。因此系统的关注点不同,相应的采用的策略也是不一样的。 传统关系数据库倾向于选择CA,而key-value数据库倾向于选择AP。对于大型网站,可用性与分区容忍性优先级要高于数据一致性,一般会尽量朝着 A、P 的方向设计,然后通过其它手段保证对于一致性的商务需求。

此处输入图片的描述

BASE

• Basically Availble – 基本可用,即支持分区失败(例如sharding碎片划分数据库) • Soft-state – 软状态/ 柔性事务,即状态信息可以在一段时间不同步,异步; • Eventual Consistency – 最终一致性,即最终的数据内容是一致即可,而不是高一致性。

BASE理论经常被拿来和ACID理论对比,ACID理论是:

  • Atomicity(原子性):指数据库操作可以组合到一起,当作单个单元处理。
  • Consistency(一致性):保证此单个单元(或事务)中的所有操作要么都成功执行,要么都不执行。
  • Isolation(隔离性):指独立的数据库事务集合以不相互冲突的方式执行。
  • Durability(持久性):保证数据库是安全的,不会异常终止。

基于ACID的关系型数据库选择的是C和P。因此能够提供很高的一致性,但是却在系统繁忙的时候不可用(Service Unavailable)。但是对于大多数互联网应用来讲,强一致性对他们来说并不一定非要满足,可用性往往是更加重要的。例如,博客网站在北京和上海的存储服务器突然不联通,北京用户和上海用户无法看到对方的评论显然要比北京用户和上海用户访问网站都返回HTTP500错误要好的多。当然,对于银行这种业务来讲,一致性是不能放弃的.

BASE模型反 ACID模型,完全不同 ACID模型,牺牲高一致性,获得可用性或可靠性: Basically Available基本可用。支持分区失败 (e.g. sharding碎片划分数据库 ) Soft state软状态 状态可以有一 段时间不同步,异步。 Eventually consistent最终一致,最终数据是一致的就可以了,而不是时时一 致。 BASE思想的主要实现有

  • 按功能划分数据库
  • sharding碎片

BASE思想主要强调基本的可用性,如果你需要高可用性,也就是纯粹的高性能,那么就要以一致性或 容错性为牺牲, BASE思想的方案在性能上还是有潜力可挖的。

最终一致性

一致性就是数据保持一致,在分布式系统中,可以理解为多个节点中数据的值是一致的。而一致性又可以分为强一致性与弱一致性。强一致性可以理解为在任意时刻,所有节点中的数据是一样的。同一时间点,你在节点A中获取到key的值与在节点B中获取到key的值应该都是一样的。弱一致性包含很多种不同的实现,目前分布式系统中广泛实现的是最终一致性。

所谓最终一致性,就是不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化。也可以简单的理解为在一段时间后,节点间的数据会最终达到一致状态。 对于最终一致性最好的例子就是DNS系统,由于DNS多级缓存的实现,所以修改DNS记录后不会在全球所有DNS服务节点生效,需要等待DNS服务器缓存过期后向源服务器更新新的记录才能实现。 类似的,还有一些其它的弱一致性实现

自从CAP理论问世以来,最终一致性基本上成为了分布式系统设计的业界标准。最终一致性一方面让系统在分区短期失效的时候仍能继续运转,另一方面也为业务提供了某种程度的异步性。然而,不同的系统对于数据不一致性的容忍度是不同的,异步性对某些业务场景也会造成限制。

下面摘自《NoSQL数据库笔谈》: 为了更好的描述客户端一致性,我们通过以下的场景来进行,这个场景中包括三个组成部分:

  • 存储系统

存储系统可以理解为一个黑盒子,它为我们提供了可用性和持久性的保证。

  • Process A

ProcessA主要实现从存储系统write和read操作

  • Process B 和ProcessC

ProcessB和C是独立于A,并且B和C也相互独立的,它们同时也实现对存储系统的write和 read操作。 下面以上面的场景来描述下不同程度的一致性:

  • 强一致性

强一致性(即时一致性) 假如A先写入了一个值到存储系统,存储系统保证后续A,B,C的读 取操作都将返回最新值

  • 弱一致性

假如A先写入了一个值到存储系统,存储系统不能保证后续A,B,C的读取操作能读取到最新 值。此种情况下有一个“不一致性窗口”的概念,它特指从A写入值,到后续操作A,B,C读取到 最新值这一段时间。

  • 最终一致性

最终一致性是弱一致性的一种特例。假如A首先write了一个值到存储系统,存储系统保证如 果在A,B,C后续读取之前没有其它写操作更新同样的值的话,最终所有的读取操作都会读取 到最A写入的最新值。此种情况下,如果没有失败发生的话,“不一致性窗口”的大小依赖于以 下的几个因素:交互延迟,系统的负载,以及复制技术中replica的个数(这个可以理解为 master/salve模式中,salve的个数),最终一致性方面最出名的系统可以说是DNS系统, 当更新一个域名的IP以后,根据配置策略以及缓存控制策略的不同,最终所有的客户都会看 到最新的值。

变体

  • Causal consistency(因果一致性)

如果Process A通知Process B它已经更新了数据,那么Process B的后续读取操作则读取A 写入的最新值,而与A没有因果关系的C则可以最终一致性。

  • Read-your-writes consistency

如果Process A写入了最新的值,那么Process A的后续操作都会读取到最新值。但是其它 用户可能要过一会才可以看到。

  • Session consistency

此种一致性要求客户端和存储系统交互的整个会话阶段保证Read-your-writes consistency.Hibernate的session提供的一致性保证就属于此种一致性。

  • Monotonic read consistency

Ref:

  • https://zh.wikipedia.org/wiki/CAP%E5%AE%9A%E7%90%86
  • https://en.wikipedia.org/wiki/CAP_theorem
  • http://www.julianbrowne.com/article/viewer/brewers-cap-theorem
  • https://foundationdb.com/key-value-store/white-papers/the-cap-theorem
  • Nosql 数据库笔谈

Comments