分布式一致性问题
数据的复制,在一个系统中更新了值后,在另一个系统中无法立刻读取到最新值,数据库复制的延时问题。
分布式系统对于数据复制的需求的原因:
a) 为了增加系统的可用性,以防止单点故障引起系统不可用
b) 为了提高系统的整体性能,通过负载均衡技术,能够让分布在不同地方的数据副本都能为用户提供服务。
2PC 二阶段提交
2PC 二阶段提交 是分布式架构下使各个节点保持一致性的一种算法。
- 二阶段提交将一个事务的处理过程分为了投票和执行两个阶段,核心是对每个事务都先采用先尝试后提交的处理方式。因此可以将二阶段提交看做一个强一致性算法。
-
阶段一:提交事务请求
- 事务询问:协调者询问所有的参与者是否可以执行事务提交操作,并等待各参与者的响应。
- 执行事务:各参与者节点执行事务操作,并且将Undo和Redo信息记入事务日志中。
- 各参与者向协调者反馈事务询问的响应:如果参与者成功执行了事务操作,那就反馈YES响应,表示事务可以执行;
如果参与者没有成功执行事务,那么就反馈给协调者No响应,表示事务不可以执行。
-
阶段二:执行事务提交
- 协调者会根据所有参与者的反馈情况来决定最终是否可以进行事务提交操作。加入协调者获得的反馈都是Yes响应,那就执行事务提交。
- 协调者会向所有的参与者节点发出Commit请求。
- 参与者接收到Commit请求后,会正式执行事务提交操作,完成事务提交后,向协调者发送Ack消息。
- 协调者接收到所有参与者反馈的Ack消息后,完成事务。
- 假如任何一个参与者反馈了No响应,或者等待超时没收到所有参与者的反馈响应,那就会中断事务。
- 协调者会向所有的节点发送Rollback请求。
- 参与者接收到Rollback请求后,会利用Undo信息来执行事务回滚操作,完成事务回滚后,向协调者发送Ack消息。
- 协调者接收到所有参与者的Ack消息后,完成事务中断。
优点:原理简单。
缺点:
- 同步阻塞:所有参与事务操作的逻辑都处于阻塞状态,
各个参与者在等待其他参与者响应的过程中,将无法进行其他任何操作。 - 单点问题:一旦协调者出现问题,那么整个二阶段提交流程将无法运转,事务资源可能会一直处于锁定状态。
- 数据不一致:当协调者向所有参与者发送Commit请求之后发生了局部网络异常或者是在没发送完Commi请求之前自身发生了崩溃,导致最终只有部分参与者收到了Commit请求。收到了Commit请求的参与者就会进行事务提交,没有收到Commit请求的参与者则无法进行事务提交,整个分布式系统就会出现数据不一致问题。
- 没有完善的容错机制:在第一阶段事务询问的过程中,如果协调者无法获得所有参与者的响应信息的话,就只能依靠自身的超时机制来判断是否需要中断事务,任意一个节点的失败都会导致整个事务的失败。
3PC 三阶段提交
由于二阶段提交的一些缺点,所以研究者在二节点提交协议的基础上进行了改进,提出了三阶段提交协议。它将二节点提交协议的提交事务请求过程一分为二,形成了CanCommit,PreCommit,doCommit三个阶段。
-
阶段一:CanCommit
- 事务询问:协调者向所有的参与者发送一个包含事务内容的canCommit请求,询问是否可以执行事务提交操作,并开始等待各参与者的响应。
- 各参与者在接收到canCommit请求后,如果自身认为可以顺利执行事务,那么就会反馈Yes响应,并且进入预备状态,否则反馈No响应。
-
阶段二:PreCommit
- 协调者会根据参与者的反馈情况来决定是否可以进行事务的PreCommit操作,假如协调者从所有参与者获得的反馈都是Yes,那么就会执行事务预提交。
- 协调者向所有参与者发出preCommit请求,并进入Prepared阶段,参与者接收到preCommit请求后,会执行事务操作,并将Undo和Redo信息记录到日志中。
- 各参与者向协调者反馈事务执行的响应。如果参与者成功执行了事务操作,那么就会反馈给协调者Ack响应,同时等待最终的指令:提交或终止。
- 假如任何一个参与者向协调者反馈了No响应,或者在等待超时后,没有收到所有参与者的反馈响应,就会中断事务。协调者向所有的参与者发出abort请求,无论是收到来自协调者的abort请求,或者是等待协调者请求的过程中出现超时,参与者都会中断事务。
-
阶段三:doCommit
- 假设协调者收到了来自所有参与者的Ack响应,那么它就会从预提交状态转到提交状态,并向所有的参与者发送doCommit请求。
- 接收者接收到doCommit请求后,会正式执行事务提交操作。在完成事务提交之后向协调者发送Ack消息。
- 协调者接收到所有参与者的反馈的Ack消息后,完成事务。
- 假设有任意一个参与者向协调者反馈了No响应,或者在等待超时后没有接收到所有参与者的反馈响应,那么就会中断事务。
- 协调者向所有参与者节点发送abort请求。参与者接收到abort请求后,会利用在阶段二中记录的Undo信息来执行事务回滚操作,
- 完成回滚操作后,会向协调者发送Ack消息。
- 协调者接收到所有参与者反馈的Ack消息后,中断事务。
优点:降低了参与者的阻塞范围,
缺点:在第三阶段,如果协调者出现问题或者协调者和参与者之间的网络出现故障。会导致参与者无法及时接收到来自协调者的doCommit或者abort请求,参与者会在等待超时之后,继续进行事务提交。出现数据的不一致性。
Paxos算法
Paxos算法是一种基于消息传递并具有高度容错性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。