CAP原理和BASE思想

分布式领域CAP理论,
Consistency(一致性), 数据一致更新,所有数据变动都是同步的
Availability(可用性), 好的响应性能
Partition tolerance(分区容错性) 可靠性

定理:任何分布式系统只可同时满足二点,没法三者兼顾。
忠告:架构师不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。

关系数据库的ACID模型拥有 高一致性 + 可用性 很难进行分区:
Atomicity原子性:一个事务中所有操作都必须全部完成,要么全部不完成。
Consistency一致性. 在事务开始或结束时,数据库应该在一致状态。
Isolation隔离层. 事务将假定只有它自己在操作数据库,彼此不知晓。
Durability. 一旦事务完成,就不能返回。
跨数据库事务:2PC (two-phase commit), 2PC is the anti-scalability pattern (Pat Helland) 是反可伸缩模式的,JavaEE中的JTA事务可以支持2PC。因为2PC是反模式,尽量不要使用2PC,使用BASE来回避。

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

BASE思想的主要实现有
1.按功能划分数据库
2.sharding碎片

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

现在NoSQL运动丰富了拓展了BASE思想,可按照具体情况定制特别方案,比如忽视一致性,获得高可用性等等,NOSQL应该有下面两个流派:
1. Key-Value存储,如Amaze Dynamo等,可根据CAP三原则灵活选择不同倾向的数据库产品。
2. 领域模型 + 分布式缓存 + 存储 (Qi4j和NoSQL运动),可根据CAP三原则结合自己项目定制灵活的分布式方案,难度高。

这两者共同点:都是关系数据库SQL以外的可选方案,逻辑随着数据分布,任何模型都可以自己持久化,将数据处理和数据存储分离,将读和写分离,存储可以是异步或同步,取决于对一致性的要求程度。

不同点:NOSQL之类的Key-Value存储产品是和关系数据库头碰头的产品BOX,可以适合非Java如PHP RUBY等领域,是一种可以拿来就用的产品,而领域模型 +分布式缓存 + 存储是一种复杂的架构解决方案,不是产品,但这种方式更灵活,更应该是架构师必须掌握的。

-----------------------------------------------------------------

CAP

CAP理论是由Brewer远在2000年的PODC会议上提出来的。CAP指的是:Consistency、Availability和Partition?Tolerance,下面简述此三者:

1、Consistency(一致性):一致性是说数据的原子性,这种原子性在经典的数据库中是通过事务来保证的,当事务完成时,无论其是成功还是回滚,数据都会处于一致的状态。在分布式环境中,一致性是说多点的数据是否一致。

2、Availability(可用性):可用性是说服务能一直保证是可用的状态,当用户发出一个请求,服务能在有限时间内返回结果。而这种可用性是不关乎结果的正确与否,所以,如果服务一致返回错误的结果,其实也可以称为其是可用的。

3、Partition?Tolerance(分区容忍性):Partition这个词不是常说的操作系统或数据库中的用语,而是指网络的分区。网络中的两个服务结点出现分区的原因很多,比如网络断了、对方结点因为程序bug或死机等原因不能访问。

对于CAP三者,Brewer给出的结论是三者在分布式环境中不能鼎力,一个分布式系统只能有限的实现两者要求,并且这个结论又被另一高人证明了一番。

一致性问题

一致性可分为强一致性和弱一致性,弱一致性又称为最终一致性。

在单机环境中,强一致性可以由数据库的事务保证。但在多机环境中,强一致性就很难做到。尽管可以使用2PC来实现分布式事务,但它的低性能(很多情况下满足不了可用性需求)使得不适合于互联网应用。这种强一致性效果的取得,其实是让提交处理过程同步化。

在多机环境中,通过使提交处理半同步半异步、或者全异步,取得最终一致性效果。例如数据库中的主从复制,在提交时就是主库同步从库异步,这对从库复制进度落后不多的场景很简单有效,但在从库落后主库很多时,如果应用还从从库读数据,就会读出脏数据,可以通过监控从库复制进度来选择读哪个从库以避免这个问题。在NOSQL模式下,以Dynamo为例,可以通过确定NRW的不同取值,可以做到同步、半同步半异步、或者全异步的效果。

最终一致性使得数据的提交效果具有延时性,而在一定的延时性范围内(比如1秒以内),应用的可用性就是OK的,比如提交后在客户端通过JS等停一段时间刷新页面就是要取得这种效果。

主从OR对等系统

像数据库这样的主从系统有着广泛的应用,它很适合于提交压力不会使得从库复制明显落后的场景。它的缺点是,当主从提交压力增大、或者存在耗时长的提交命令时,从库复制进度会明显落后于主库。在Cache+DB的应用场景下,Cache的填充时机和策略也会受到主从模式影响。如果在一个Session中提交DB后作废Cache,而由后续的(或并发的)另一个Session来再次设置Cache、并且数据是从从库获取,就很有可能缓存住脏数据,如果Cache时间很长,那问题可能就很严重了。可以变通的策略是,在一个Session中提交DB后不是作废Cache,而是更新Cache,并且数据是从主库获取或者直接从应用环境获取。主从的另一个问题是,它有提交单点,但是,如果主从能满足应用需要,在具有完备的主备切换的保证下,这个单点问题并不见得有多大。

因为Dynamo的时兴,对等系统成为另一种选择。对等系统解决了单点问题,有着高分区容忍性,但它的效果仍得商榷。NRW的不同取值会影响读写数据效果,多点提交带来的冲突解决也是个问题,尽管通常采用高版本替换低版本的粗暴策略。现在的NOSQL对等系统存储的是简单的kv,并且可以采用加机器来扩容,所以性能方面应该是可接受的(尽管常见的单机kv存储性能要比数据库高很多,但在对等系统中,因为其复杂性,换算下来单机的性能并不见得有多高)。

SQL和NOSQL各有其优缺点。如果存储一些实体数据并且查询提交只是根据唯一标识来,使用NOSQL也许就很合适。但像复杂的关系数据,使用SQL就更合适些。而就提交模式来说,如果并发提交的数据隔离性不好(比如需要同时对同一个数值做更新),那么对等系统的提交冲突就会增多,数据的正确性就会受到影响。

BASE

上面提到,在分布式环境中,CAP只能取两者。但是,因为网络分区的情况不可避免,并且它对可用性有着重要影响,所以互联网中的分布式系统多在一致性方面做些折中。虽然不能达到强一致性,但可以根据应用特点采用适用的手段来达到够用的一致性效果。比如,对于微博系统,当用户新增一条消息,能够达到用户能看到刚才发的消息、而他的follower们能在尽快时间看到他新发的消息的效果就可以了。而在实现时,就可以结合同步和异步多种策略、SQL+NOSQL多种存储方案来满足应用需要。

BASE(Basically?Available、Soft?state、Eventually?consistent)是对CAP中的AP的延伸。

在单机环境中,ACID是数据的属性;而在分布式环境中,BASE就是数据的属性。ACID有“尖刻”之含义,所以单机环境的数据有着很高的要求。而因为分布式环境的网络分区性及复杂性,对数据也只能有“基本”的要求了。

从ACID到CAP和BASE,从单机到分布式,从SQL到NOSQL,互联网应用的大规模发展促使不断出现可替代旧方案的新技术。在技术选型方面,重要的是根据自己的应用特点选择自己能驾驭的技术。而现实的应用场景,也大多是多种技术方案的结合。


 

原文地址:https://www.cnblogs.com/liaomin416100569/p/9331300.html