一.CAP理论
一个分布式系统不可能同时满足一致性
、可用性
和分区容错性
这三个基本需求,最多只能同时满足其中的两项。
1、一致性(C-Consistency)
一致性指“all nodes see the same data at the same time
”,即更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致。这里的一致性更多是指强一致性,对于一致性,可以分为从客户端和服务端两个不同的视角。
- 从
客户端
来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题
。多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性
。如果能容忍后续的部分或者全部访问不到,则是弱一致性
。如果经过一段时间后要求能访问到更新后的数据,则是最终一致性
。 - 从服务端来看,则是
更新如何复制分布到整个系统,以保证数据最终一致
。一致性是因为有并发读写才有的问题,因此在理解一致性的问题时,一定要注意结合考虑并发读写的场景。
2、可用性(A-Availability)
可用性指“Reads and writes always succeed
”,即服务一直可用,对于请求总是能在限的时间内返回结果。
对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。所以,一般我们在衡量一个系统的可用性的时候,都是通过停机时间
来计算的。
可用性分类 | 可用水平(%) | 年可容忍停机时间 |
---|---|---|
容错可用性 | 99.9999 | <1 min |
极高可用性 | 99.999 | <5 min |
具有故障自动恢复能力的可用性 | 99.99 | <53 min |
高可用性 | 99.9 | <525min |
商品可用性 | 99 | <5256 min |
通常我们描述一个系统的可用性时,都用 n 个9来表示,比如:我们说某个系统可用性可以达到5个9,意思就是说他的可用水平是 99.999%这是一个极高的要求。
( 1 - 0.999999 ) * 365 * 24 * 60 = 0.5256 min
( 1 - 0.99999 ) * 365 * 24 * 60 = 5.256 min
( 1 - 0.9999 ) * 365 * 24 * 60 = 52.56 min
( 1 - 0.999 ) * 365 * 24 * 60 = 525.6 min
( 1 - 0.99 ) * 365 * 24 * 60 = 5256 min
好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。一个分布式系统,上下游设计很多系统如负载均衡、WEB服务器、应用代码、数据库服务器等,任何一个节点的不稳定都可以影响可用性。
3、分区容错性(P-Partition tolerance)
分区容错性指“the system continues to operate despite arbitrary message loss or failure of part of the system
”,即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务(除非整个网络故障,分布式系统在任何网络或者单点故障时仍能对外提供满足一致性和可用性的服务)。
分区容错性和扩展性紧密相关。在分布式应用中,可能因为一些分布式的原因导致系统无法正常运转。好的分区容错性要求:应用虽然是一个分布式系统,而看上去却好像是在一个可以运转正常的整体。比如分布式系统中有某一个或者几个机器宕掉了,其他剩下的机器还能够正常运转满足系统需求,或者是机器之间有网络异常,将分布式系统分隔未独立的几个部分,各个部分还能维持分布式系统的运作,这样就具有好的分区容错性。
分区容错性必须存在(用分区来尽大化来容错):
传统系统是将数据放在一台服务器上,那么随着数据的增加,一台服务器是不能满足要求的,就要将数据进行分区存储(这也是传统架构到互联网架构的转变);
而分布式系统不仅仅只是将数据分区,还需要保证数据的安全性,那么就需要数据副本(默认是3份),将数据冗余起来,来保证容错特性,在节点故障后仍然可以正常使用。这样将数据分区,还提高了并发性,使客户端的请求不一定非要定向到某台服务器,可以从任何的节点读取数据,所以分布式的基础是分区容错。
但是分区容错也会带来两军问题,因为分区间的数据要进行同步,但是网络是不可靠的,在同步数据的时候,会存在存在网络问题(timeout),也就是我们所说的两军问题。这也就要求我们在数据一致性和数据高可用中二选一,但是没办法保证数据强一致性。
选择 | 说明 |
---|---|
满足AC(放弃P) | 将数据和服务都放在一个节点上,避免因网络引起的负面影响,充分保证系统的可用性和一致性。但放弃P意味着放弃了系统的可扩展性。 |
满足PC(放弃A) | 当节点故障或者网络故障时,受到影响的服务需要等待一定的时间,因此在等待时间里,系统无法对外提供正常服务,因此是不可用的。 |
满足AP(放弃C) | 系统无法保证数据的实时一致性,但是承诺数据最终会保证一致性。因此存在数据不一致的窗口期,至于窗口期的长短取决于系统的设计。 |
两军模型:
两军问题的根本问题在于信道的不可靠(网络不可靠),反过来说,如果传递消息的信道是可靠的,两军问题可解。然而,并不存在这样一种信道,所以两军问题在经典情境下是不可解的。
二.BASE基础
BASE 理论是基于 CAP 理论的,是对 CAP 理论的延伸。其核心思想是即使无法做到强一致性,但分布式系统可以根据自己的业务特点,采用适当的方式来使系统达到最终的一致性
。BASE 是指基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency)
1.基本可用(Basically Available)
当分布式系统出现不可预见的故障时,允许损失部分可用性,保障系统的"基本可用";体现在"时间上的损失"和“功能上的损失"。
示例:电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。
2.最终一致性(Eventually consistent)
系统中所有的数据在经过一段时间的数据同步后,最终能够达到一个一致的状态。弱一致性
和强一致性相反,最终一致性是弱一致性的一种特殊情况。
3.软状态(Soft state)
软状态是指允许系统中的数据存在中间状态,而该中间状态不会影响系统整体可用性。允许系统的不同节点的数据副本之间的数据同步过程存在延时,并认为这种延时不会影响系统可用性。
ACID和BASE的区别与联系
ACID 是传统数据库常用的设计理念,追求强一致性模型。BASE 支持的是大型分布式系统,提出通过牺牲强一致性获得高可用性。
ACID 和 BASE 代表了两种截然相反的设计哲学。
在分布式系统设计的场景中,系统组件对一致性要求是不同的,因此ACID和BASE又会结合使用。
三.2PC、3PC
1、XA协议
查询百度百科,给出的定义是:XA 协议由 Tuxedo 首先提出的,并交给 X/Open 组织,作为资源管理器(数据库)与事务管理器的接口标准
。目前,Oracle、Informix、DB2 和 Sybase 等各大数据库厂家都提供对 XA 的支持。XA 协议采用两阶段提交方式
来管理分布式事务。XA 接口提供资源管理器与事务管理器之间进行通信的标准接口。XA 协议包括两套函数,以 xa_ 开头的及以 ax_ 开头的。
2、2PC
两阶段提交又称 2PC(two-phase commit protocol),2PC 是一个非常经典的强一致、中心化的原子提交协议
。这里所说的中心化是指协议中有两类节点:一个是中心化协调者节点(coordinator)
和N个参与者节点(partcipant)
。
(1)优点
XA 协议比较简单,而且一旦商业数据库实现了 XA 协议,使用分布式事务的成本也比较低。
(2)缺点
1、性能问题–同步阻塞
从 2PC 流程上我们可以看得出,二阶段提交的第一阶段中,协调者
需要等待参与者
的响应,如果没有接收到任意参与者的响应,这时候进入等待状态,而其他正常发送响应的参与者,将进入阻塞状态,将无法进行其他任何操作,只有等待超时中断事务,极大的限制了系统的性能。
2、协调者单点故障问题–单点故障
事务协调者是整个 XA 模型的核心,一旦事务协调者节点挂掉,那么整个二阶段提交将无法运转,那么其他参与者将会一直处于锁定事务资源的状态中
,从而导致参与者节点始终处于事务无法完成的中间状态。
协调者宕机,可以采用重新选举一个协调者的方式来解决单点故障问题,但是还是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题。
3、丢失消息导致的数据不一致问题
在第二个阶段,当协调者向参与者发送 commit 请求之后,发生了局部网络异常或者在发送commit 请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了 commit 请求。而在这部分参与者接到 commit 请求之后就会执行 commit 操作。但是其他部分未接到 commit 请求的机器则无法执行事务提交,于是整个分布式系统便出现了数据部一致性的现象。
4、二阶段无法解决的问题
协调者在发出 commit 消息之后宕机,而唯一接收
到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,但这条事务的状态也是不确定的,没人知道事务是否被已经提交成功。
3、3PC
3PC 是 2PC 的改进版本,将 2PC 的第一阶段:准备事务阶段一分为二
,形成了 CanCommit、PreCommit 和 doCommit 三个阶段组成的事务处理协议。其核心理念是:在询问的时候并不锁定资源
,除非所有参与者都同意了,才开始锁资源。
和二阶段提交对比,三阶段提交主要是在2PC的第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。
(1)优点-解决的2PC问题
1、降低同步阻塞
在 3PC 中,第一阶段并没有让参与者直接执行事务,而是在第二阶段才会让参与者进行事务的执行
。大大降低了阻塞的概率和时长。
相比较2PC而言,3PC 对于协调者(Coordinator)和参与者(Partcipant)都设置了超时时间
,而2PC只有协调者才拥有超时机制。这个优化点
,主要是避免了参与者在长时间无法与协调者节点通讯(协调者挂掉了)的情况下,无法释放资源的问题,因为参与者自身拥有超时机制会在超时后,自动进行本地commit 从而进行释放资源。而这种机制也侧面降低了整个事务的阻塞时间和范围。
2、提升了数据一致性
2PC中有一种情况会导致数据不一致,如:在 2PC 的阶段二中,当协调者向参与者发送commit请求之后,发生了网络异常,只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式便出现了数据不一致性的现象。
这种情况在3PC的场景中得到了很好的解决,因为在3PC中,如果参与者没有收到协调者的commit请求,他不会一直阻塞,过一段时间之后,他会自动执行事务。这就解决了那种协调者发出commit之后。
(1)缺点
1、数据不一致
在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者abort请求时,会在等待超时之后,会继续进行事务的提交。
所以,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。即:无论是二阶段提交还是三阶段提交都无法彻底解决分布式的一致性问题
。
2PC:协调者在只给部分参与者发送了Commit请求,那就会出现部分参与者执行了Commit,部分没有提交,出现不一致问题。
3PC:一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态,但是这种机制也会导致数据一致性问题。
there is only one consensus protocol,and thats Paxos – all other
approaches are just broken versions of Paxos。
意即世上只有一种一致性算法,那就是Paxos,所有其他一致性算法都是 Paxo 算法的不完整版。
4、总结
(1)2PC/3PC 可以用来处理分布式事务
,能够很好的提供强一致性
和强事务性
,但相对来说延迟比较高,比较适合传统的单体应用。在同一个运用可以访问多个数据库的前提下可以使用(多数据源),但不适合高并发和高性能要求的场景。
(2)2PC/3PC 可以用来处理数据一致性
,但是很少使用,更多使用的是是 Paxos 或者基于 Paxos 的变种。
参考资料:
https://blog.youkuaiyun.com/csdnsevenn/article/details/100868896