1、NoSQL运动
自从上世纪80年代以降,关系型数据库(即传统的OLTP和OLAP数据库)一直都是后端业务系统的主导,能够满足很多需求。但是,随着数据量的激增、对查询响应要求提升、越来越多非结构化数据泛滥等原因,关系型数据库的领域面临挑战,因此催生了NoSQL(非关系型、not only SQL)运动——这个词在世纪之交才出现,但是NoSQL思想和数据库出现得要早得多。
各式各样的NoSQL数据库在分布式、实时性、可扩展性、Schema-less等方向都取得了突破。下图示出了关系型数据库和NoSQL的区别,以及4种NoSQL存储模式——键值、列族、图和文档。
NoSQL数据库几乎都不会提供ACID事务保证,也不将ACID作为指导思想,毕竟在分布式系统上实现ACID太难了。它们的基础是分布式领域的两个著名理论,即CAP和BASE。
2、CAP理论
CAP理论由Eric Brewer在2000年作为猜想提出,并在2002年由Seth Gilbert和Nancy Lynch证明了其正确性。CAP理论的内容为:
在分布式系统中,不可能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(partition tolerance)三大特征,最多只能满足其中两者
2.1 一致性
Every read receives the most recent write or an error.
对于客户端向分布式系统的读请求,要么督导最新的数据,要么失败
也就是说,不管数据如何更新,它在多个副本之间都可以保持精准、立即的同步,所有客户端取得的数据永远是“正确”的。
由此可见,CAP中的“一致性”与 ACID中的“一致性”虽然不是一个概念,但它仍然指的是最强的一致性。
2.2 可用性
Every request receives a (non-error) response, without the guarantee that it contains the most recent write.
字面意思是说,对分布式系统的请求一定会得到非错误的响应,但不保证响应一定包含最新写入的数据。也就是说从客户端的角度看,不会出现向分布式系统发出请求但得不到任何有意义的响应的情况,即系统提供的服务对客户端而言不能宕机,一直都是可用的。
2.3 分区容错性
The system continues to operate despite an arbitrary number of messages being dropped (or delayed) by the network between nodes.
字面意思是说,就算分布式系统内部节点之间的通信出了问题(如延迟、丢包),系统仍然能正常运作。这里的“分区”是指网络分区(network partition)——网络中有节点挂掉时,原网络分解为两个或多个子网络的过程。也就是说,系统不会因为内部的网络不可靠就停止服务。
2.4 CP/AP的抉择与“CAP+ NoSQL铁三角”
由于一致性、可用性、分区容错性三者只能得其二,所以必然有所取舍。
但是,考虑到是分布式系统,分布式系统总是有多个节点组成,网络问题几乎必定会出现。
所以分区容错性必须要保证,一致性和可用性之间做出权衡,即选择CP还是AP的问题
考虑下面的极简模型:有两个数据中心,它们通过网络进行Replication,即数据在其中一个数据中心发生更改,就会立即通过网络传输到另外一个数据中心。每个客户端同时只能连接到一个数据中心的Application做读写操作。
假设Replication连接断掉了----即产生了网络分区,我们有两种选择:
- AP:仍然允许所有客户端读写,但是两个数据中心之间不再同步,他们的数据就会逐渐地变得不同,即牺牲一致性,保证可用性
- CP:只允许连接到一个数据中心上的客户端读写,另一个停止服务,直到Replication连接恢复,即牺牲可用性,保证一致性
Consistent, Available (CA) Systems have trouble with partitions and typically deal with it with replication. Examples of CA systems include:
- Traditional RDBMSs like Postgres, MySQL, etc (relational)
- Vertica (column-oriented)
- Aster Data (relational)
- Greenplum (relational)
Consistent, Partition-Tolerant (CP) Systems have trouble with availability while keeping data consistent across partitioned nodes. Examples of CP systems include:
- BigTable (column-oriented/tabular)
- Hypertable (column-oriented/tabular)
- HBase (column-oriented/tabular)
- MongoDB (document-oriented)
- Terrastore (document-oriented)
- Redis (key-value)
- Scalaris (key-value)
- MemcacheDB (key-value)
- Berkeley DB (key-value)
Available, Partition-Tolerant (AP) Systems achieve "eventual consistency" through replication and verification. Examples of AP systems include:
- Dynamo (key-value)
- Voldemort (key-value)
- Tokyo Cabinet (key-value)
- KAI (key-value)
- Cassandra (column-oriented/tabular)
- CouchDB (document-oriented)
- SimpleDB (document-oriented)
- Riak (document-oriented)
Hbase为什么是CP?
Hbase的数据是按照RowKey分布在各个Region(即RegionServer)上的。在稳定的Habse集群中,不管访问同一个RowKey多少次,最终都会指向同一个RegionServer,并且Habse保证对行的更新操作和新行的put操作都是原子的,所以是强一致的。
但是,如果RegionServer因为网络分区不可达,HMaster将其视为失败,并触发它持有的region的WAL重放(replay)。在整个重放过程中,这些region都不能提供服务,所以不能保证可用性。如果正在重放的region也能被读写,那么就一定会返回不一致的数据
2.5 CP/AP的分类是严谨的么?
Martin Kleppman(大名鼎鼎的《Designing Data-intensive Applications》一书的作者)在2015年写的一篇博文《Please stop calling databases CP or AP》。从这题目也可以看出来,他认为用CAP原理来界定是很不科学的,观点如下:
- CAP的定义太狭窄,如:一致性实际上指的是最强的线性一致性(linearizability);可用性要求所有节点都能做出响应,与real-world可用性差别甚大;分区容错性的真正含义是容忍异步的不可靠网络,名称过于误导。
- 只考虑了单变量的读写,完全没考虑事务。
- 除了网络问题之外,没考虑其他很多异常情况,如节点出错、磁盘用尽等,也没有将延迟问题算在内(例如,一般不会认为5分钟才能返回查询结果的系统是“可用”的)。
Martin Kleppman进一步指出,CAP理论过于一刀切了,而人们总是强行将分布式系统的设计塞入CP或AP其中之一,丢失了很多细节,并且原来的consistency、availability的含义也改变了。甚至有不少系统的实现都同时不满足严格的C和A,只满足P,虽然有些尴尬,但也不意味着就是糟糕的方案。他另外写了一篇《A Critique of the CAP Theorem》提出了CAP分类的替代方案,就不再赘述了。这两篇都很有意思。
3、BASE理论
BASE理论由Dan Prichett在2008年藉由论文《BASE:An ACID Alternative》提出。它是三个词组的首字母缩写,即:
- 基本可用(basically available)
- 软状态(soft state)
- 最终一致性(eventually consistent)
文字游戏很有意思,acid(“酸”)与base(“碱”)正好是对立的,当然这不代表RDBMS和NoSQL是水火不容。
BASE是对CAP一致性和可用性权衡的结果,来源于对大规模互联网分布式实践的总结,是基于CAP理论演化来的。
3.1 基本可用
所谓基本可用,是指分布式系统在出现故障时,允许损失部分可用性,以保证系统基础运转仍然正常。这在实际操作中并不少见,如:
- 正常情况下,数据库需要在200ms内返回查询结果,但由于故障,使得响应时间延长到了2s,即响应的延迟增加了;
- 在电商大促高峰(特别是秒杀)时,为了维护整个系统的稳定性,部分订单会不成功,用户会被引导至降级页面,即牺牲部分功能。
3.2 软状态
软状态也称为弱状态,是指允许系统中的数据存在中间状态,并且该中间状态不影响系统的可用性。翻译成人话,就是分布式系统在不同节点之间进行数据同步的过程中允许有一定的不同步性。
3.3 最终一致性
最终一致性是指系统中的所有副本在经过一段时间的同步之后,最终总能够达到一致的状态。它是BASE的终极目标,也是任何分布式系统在实践中必须达到的目标。
最终一致性是个复杂的话题,本文已经非常之长了,就不再展开了。引用一下Werner Vogels在2008年的文章《Eventually Consistent Revisited》中的观点,他认为最终一致性是特殊的弱一致性:系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。
那么有哪些手段保证最终一致性呢?比较重量级的方案就是直接引入分布式事务,如2PC、3PC、TCC等,轻量级的方案都可以在业务中自己实现,如重试+幂等性保证、状态机、重做日志等,不再一一赘述。
来源:https://mp.weixin.qq.com/s/biwE4sADMcGOGhyEqufEJg
来源:https://blog.nahurst.com/visual-guide-to-nosql-systems