分布式系统中,人们为了保障多个节点在进行全局事务操作的一致性,提出了很多分布式算法,其中比较著名的有二阶提交协议(Two Phase Commitment Protocol)、三阶提交协议(Three Phase Commitment Protocol)和Paxos算法,本文主要讲述2pc和3pc算法,paxos算法会留到下一篇博客中。
2pc算法:
二阶段提交算法顾名思义,主要由两个阶段组成,分别是事务的投票阶段和提交执行阶段。
阶段一:投票请求阶段
1、事务询问
协调者向所有参与者发送事务内容,询问是否可以提交事务内容,并等待各参与者的响应。
2、 执行事务
参与者执行事务操作,并记录Undo 和 redo日志(这里的参与者已经执行了事务操作)
3、 各参与者向协调者反馈事务询问响应。
如果参与者成功执行了事务操作,反馈YES,表示可以执行,否则反馈NO。
阶段一则为投票阶段。各参与者尝试着执行事务并反馈结果
阶段二: 提交执行阶段
阶段二分两种情况:A、事务正常执行。B、事务执行失败
A、事务正常执行
- 所有参与者反馈YES,协调者向参与者节点发出commit请求。
- 参与者收到请求后正式执行提交操作并在完成提交之后释放在整个事务执行期间占用的事务资源。
- 参与者执行后反馈Ack消息。
- 协调者接收到Ack消息后完成事务
B、如果过程中接收到一个或多个NO,事务执行失败
1、发送回滚请求。
2、事务回滚
3、反馈回滚结果
4、中断事务
下图分别是A、B两种情况的流程图:
总结:2pc是强一致性算法,优点是实现简单,缺点也很明显,其中最大的问题是同步阻塞,在第二阶段开始,协调者等待参与者返回的过程中,一旦某个参与者不能及时返回,整个系统会阻塞,同时还有一个问题就是如果协调者在发出commit请求后某个参与者crash或者网络断开,那么就会出现数据不一致的情况。接下来介绍3pc算法:
3PC算法:
3pc是2pc的改进版本,主要是给协调者和参与者都引入了超时机制,同时在第一阶段和第二阶段过程中加 入了一个准备阶段,保障了数据的一致性。
阶段一:canCommit
协调者向参与者发送canCommit消息和事务信息,参与者收到后,会判别自己是否可以执行该事务,如果可以执行就返回 yes,不可以则返回no.如果协调者收到任何一个no或者参与者超时,事务终止,同时会通知参与者事务终止,只有在超时 时间内收到所有yes,才能进入下一阶段。(相对于参与者来说,在反馈完第一阶段的canCommit后,如果等待协调者发送preCommit也超时的话也会终止事务)
阶段二:preCommit
本阶段协调者会发送preCommit消息给所有参与者,所有参与者收到后会开始执行事务,并记录undo和redo日志,返回ACK消息。
阶段三:doCommit
协调者只有在接收到所有ACK消息后会发送doCommit,否则会给参与者发出终止消息,事务回滚。(相对于参 与者来说,只要接受到一个preCommit消息并返回了ACK,如果此时协调者崩溃或者超时,各个参与者则会继续完成这 次commit。所以在第三阶段,如果是协调者出错参与者没错的情况下,参与者会继续完成本次提交;如果是协调者没错,参与者出错,则本次事务终止。)
总结:3pc对比2pc来说增强了数据一致性, 同时引入了双方超时机制,减小了阻塞。但是缺点依旧存在,主要是无法避免网络分区(网络分区:在网络不好的情况下,高延迟被区分成失败)问题,因为3pc采用了失败-停止的模式,所以一旦网络延迟高就会失败。
参考:
https://en.wikipedia.org/wiki/Three-phase_commit_protocol
http://www.mamicode.com/info-detail-890945.html
《从Paxos到Zookeeper分布式一致性原理与实践》