CAP
CAP原则又被称为是CAP定理,它是指在一个分布式系统中,一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)三者的统称。在一个分布式系统中是三者是不可兼得的。
一致性:在一个分布式系统中,所有的数据以及数据的备份中是否存在相同的值,也就是说在同一时刻所有数据节点上的数据是否是一致的。
可用性:在一个分布式集群中一部分节点因为各种原因发生故障之后,整个的集群是否能够响应客户端的请求。也就是说系统是否能够在部分节点故障之后展现出正常的服务能力。
分区容错性:在一个分布式系统中如果系统不能在同一时间内达成数据一致性,那就说明该分布式系统发生了分区,也就必须在一致性和可用性之间做出选择,对于一个系统来讲,出现分区的情况可能是因为通信而导致的。而通信问题又是不易被解决的,所以只能满足CP或者是AP二者之一。
二阶段提交协议
关于事务的相关内容,在我们之前的分享中也提到过。而这里所提到的分布式事务是指对多个数据的操作事务的组合,在一个分布式系统中,各个节点都是在物理上相对来说独立的,并且这些节点都是通过网络来进行沟通和协调调用的。在之前的介绍中我们知道网络问题是在系统运行中不可避免的问题。所以说为了解决分布式系统间事务的一致性就出现了二阶段提交的做法。
二阶段提交是指在计算机网络以及数据库领域中,为了是的分布式数据库的所有节点在进行事务操作的时候能够保证数据一致性的一种实现算法。在分布式系统中,每个节点都可以单独知道自己的连接状态,并且可以知道自己的操作是否成功,却没有办法知道其他节点的操作是否成功。
这个时候,如果存在一个事务跨越多个节点,为了保证该事务的ACID的特性,就需要引入一个作为协调者的组件来统一控制所有节点的操作结果,并且最终让所有参与节点完成正常的事务提交操作。所以二阶段提交的算法思路可以简单的概况为:参与者将操作成败通知到协调者,然后再由协调者根据所有参与者反馈的情况来决定各个参与者是否提交成功,从而让整个的事务显示成功或者是失败。整个过程如下。
准备阶段
事务协调者给每个参与者都发送一个准备的指令消息,每个参与者要么直接返回失败,要么就执行本地事务,然后写入到redo或者undo的重做日志中但是不提交事务。
提交阶段
如果协调者收到参与者的失败或者调用超时的消息,那么就直接给所有的参与者发送一个回滚的消息,否则就发送一个提交的消息,参与者会根据协调者发送的指令来执行提交或者是回滚操作。并且释放所有事务处理过程中的锁资源,如下图所示。
我们将准备阶段、提交阶段统一为二阶段提交。但是二阶段提交也是有它的缺点的。
- 同步阻塞问题:在执行的过程中所有参与者的调用任务都是阻塞来执行的。所以对于性能消耗比较大。
- 单点故障问题:由于所有的请求调用都要经过协调者的调用,所以在协调者发生单点故障的时候,所有的参与者都会受到影响。
- 数据不一致性问题:在提交阶段,由于协调者向参与者发送消息之后,如果发生了网络的局部异常,或者是在发送提交请求过程中协调者发生了故障,导致只有一部分的参与者收到了提交的消息,这个时候就会导致没有收到提交请求的部分节点发生回滚,而受到请求的节点执行提交,最终导致整个分布式系统中的数据不一致问题。
- 协调者故障导致事务状态丢失:如果在协调者发出了提交请求之后,发生了宕机,并且唯一接收这条消息的参与者也发生了宕机,整个时候由于选举机制产生了新的协调者,由于整个时候旧的协调者出了问题,对应的事务的状态也就无法考证,无法判断出到底是该事物被提交了还是发生了其他情况。
基于二阶段提交出现的这些问题,就出现了三阶段提交的算法。
三阶段提交协议
三阶段提交协议,是根据二阶段提交协议做了改进,引入了如下的一些处理机制
- 引入了超时机制:在协调者和参与者中引入了超时机制,如果协调者长时间收不到参与者的反馈,那么就会默认参与者执行失败。
- 在准备阶段与提交阶段中间加入一个预备阶段,这样可以保证在最终提交任务之前各个参数与节点的状态是一致的,也就是说除了加入了超时机制,还引入了第三个阶段,这样就将二阶段提交改成了三阶段提交。
CanCommit阶段
协调者向参与者发送提交请求,参与者如果可以提交就返回一个成功的响应,如果不能提交则返回失败的响应。
PreCommit阶段
协调者根据参与者反馈的结果来做出是否执行的操作判断,有如下两种可能。
第一种、所有的参与者都反馈的是成功的请求,这样就要开始执行该事务了。
第二种、如果有一个参与者反馈的是失败,那么在超时等待之后就会中断事务执行,进行事务回滚。
DoCommit阶段
在这个阶段来完成真正的事务提交,包括协调者发送提交的请求,参与者提交事务,参与者反馈结果等,如下图所示。
总结
上面我们介绍了分布式事务的2PC和3PC,二者各有优势也各有不足,在实际操作过程中我们可以根据实际的需求来选择适合的操作方式来完成分布式事务的实现。