前言
上一章通过两个故事总结了分布式系统难以解决的三大问题(分区容忍,可用性,一致性)中的可用性与一致性,让自己更加深刻理解了他们的概念。这一章我总结一下关于2PC,3PC的概念与设计思路,以及他们的优缺点。
在分布式系统中,每一个节点虽然都能够明确地知道自己在进行事务操作过程中的结果是成功或失败,但却无法直接获取到其他分布式节点的操作结果。
这里2PC,3PC的PC为Phase Commit(阶段提交)的意思。
一、2PC
通常,二阶段提交(2PC)协议被认为是一种一致性协议,用来保证分布式系统数据的一致性。流程中需要两种角色来完成整个工作,一个是协调者,一个是参与者。
流程如图:
阶段一:提交事务请求,这里相当于一个投票表决的环境,分为三步
1.事务询问
协调者向所有参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。
2.执行事务
各参与者节点执行事务操作,并将Undo与Redo信息记入事务日志中。
3.询问响应
如果参与者节点事务执行成功,那么反馈Yes,表示可以提交,否者返回No,表示不可以提交。
阶段二:执行事务提交或终端事务
a.如果协调者收到所有的参与者反馈的消息都是Yes,那么执行事务提交:
1.发送提交请求
协调者想所有参与者发送 Commit请求。
2.事务提交
参与者收到Commit请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。
3.反馈事务提交结果
参与者在完成事务提交之后,向协调者发送Ack消息。
4.完成事务
协调者接收到所有参与者反馈的Ack消息后,完成事务。
b.如果任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接收到所有参与者的响应,那么就会中断事务:
1.发送回滚请求
协调这向所有参与者节点发出 Rollback 请求。
2.事务回滚
参与者接收到 Rollback 请求后,会利用在第一阶段记录的 Undo 信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。
3.反馈事务回滚结果
参与者完成事务回滚之后,向协调者发送 Ack 消息。
4.中断事务
协调者接收到所有参与者反馈的 Ack 消息后,完成事务中断。
以上就是二阶段提交的整个过程。
优点:简单、易实现
缺点:同步阻塞、单点问题、脑裂(网络分区)
二、3PC
针对2PC的一系列问题,研究者对提交协议进行了改进,提出了三阶段提交协议。
流程如图:
阶段一:CanCommit
1.事务询问
协调者向所有参与者发送一个包含事务内容的 canCommit 请求,询问是否可以执行事务提交操作,并开始等待各参与者的响应。
2.响应询问
参与者在接收到来自协调者的 canCommit 请求后,正常情况下,如果其自身认为可以顺利执行事务,那么会反馈 Yes 响应, 并进入预备状态,否则发聩 No 响应。
阶段二:PreCommit
a.如果协调者收到所有的参与者反馈的消息都是Yes,那么执行事务预提交:
1.发送预提交请求
协调者向所有参与者节点发出 preCommit 的请求,并进入 Prepared 阶段。
2.事务预提交
参与者接收到 preCommit 请求后,会执行事务操作,并将Undo 和 Redo 信息记录到事务日志中。
3.反馈事务提交结果
如果参与者成功执行了事务操作,那么就会反馈给协调者 Ack 响应,同时等待最终的指令:提交(commit)或终止(abort)。
b.如果任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接收到所有参与者的响应,那么就会中断事务:
1.发送中断请求
协调者向所有参与者节点发出 Abort 请求。
2.中断事务
无论是收到来自协调者的 abort 请求,或者是在等待协调者请求过程中出现超时,参与者都会中断事务。
阶段三:doCommit
a.如果协调者收到所有的参与者反馈的 Ack 消息,那么执行事务提交:
1.发送提交请求
进入这一阶段,假设协调者处于正常工作状态,并且它接收到了来自所有参与者的 Ack 响应,那么它将从 “预提交” 状态转换到 “提交” 状态,并向所有参与者发送 doCommit 请求。
2.事务提交
参与者接收到 doCommit 请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。
3.反馈事务提交结果
参与者完成事务提交之后,向协调者发送 Ack 消息。
4.完成事务
协调者接收到所有参与者反馈的 Ack 消息后,完成事务。
b.如果在阶段二,参与者反馈 Ack 出问题或者超时,那么执行事务回滚请求:
同2PC的事务回滚请求
优点:降低阻塞
缺点:数据不一致、单点问题、脑裂(网络分区)
所以2PC、3PC在分布式事务上还是存在很多不足的问题,接下来我们看看 Paxos 是怎么解决这些问题的。