分布式系统数据一致性-3PC(三阶段提交)
- 准备通过一个系列聊下分布式系统一致性问题,主要会介绍两阶段提交(2pc),三阶段提交(3pc),vector clock,paxos, zap等。
二阶段提交的主要问题
- 同步阻塞(三阶段提交主要解决的问题)
- 单点问题
- 脑裂问题
- 过于保守
场景分析
- 在2PC中一个participant的状态只有它自己和coordinator知晓,假如coordinator提议后自身宕机,在watchdog启用前一个participant又宕机,其他participant就会进入既不能回滚、又不能强制commit的阻塞状态,直到participant宕机恢复。
解决思路
- 能不能去掉阻塞,使系统可以在commit/abort前回滚(rollback)到决议发起前的初始状态。
- 当次决议中,participant间能不能相互知道对方的状态,又或者participant间根本不依赖对方的状态。
3PC过程
- 三阶段提将二阶提交事物请求分成2个阶段,形成了canCommit, preCommit, doCommit三个阶段。
阶段 1(canCommit)
- 1.事物询问:协调者向所有参与者发送canCommit请求,询问是否可以执行事务操作,并等待反馈。
- 2.参与者反馈事务相应:参与者接受到协调者的事务执行请求之后,如果自身状态正常可以执行事务,反馈Yes,并进入准备状态,否则返回No。
阶段二(preCommit)
- 执行事务预提交(如果参与者反馈都是Yes)
- 1.发送预条请求:协调者向所有参与者发送preCommit请求,并进入prepared阶段。
- 2.事务预提交:参与者开始执行事务,并将记录undo和redo日志。
- 3.反馈执行结果: 如果参与者执行成功,则反馈ACK给协调者,并等待最终的commit或abort。
- 中断事务(如果有一个参与者反馈是No)
- 1.发送abort请求。
- 2.中断事务:无论收到协调者的abort请求或者等待请求超时都会中断事务。
阶段三(doCommit)
- 执行事务提交
-
- 发送提交请求: 如果协调者状态正常并且受到了所有参与者的ACK,那么他将从预提交状态变成提交状态,并向参与者发送doCommit请求。
-
- 事务提交:参与者收到doCommit请求之后正式提交事务,提交完成释放事务资源。
-
- 反馈结果: 参与者向协调者发送ACK。
-
- 完成事务:协调者受到所有参与者的ACK之后完成事务。
-
- 中断事务(假设协调者状态正常,参与者反馈了No或者等待超时没有受到反馈)
-
- 发送abort请求:向参与者发送中断请求。
-
- 事务回滚:参与者收到abort请求之后回滚事务,利用undo日志,并且释放资源。
-
- 反馈结果:参与者反馈回滚ACK。
-
- 中断事务:协调者受到参与者的ACK,中断事务。
-
注意点(阶段三可能有2个故障)
- 协调者出现问题。
- 协调者何参与者之间网络故障。
- 无论出现以上哪种问题,参与者都会在等待超时之后继续提交事务。
优缺点
优点
- 三阶段提交阻塞范围小(阶段一不阻塞),并且能够在出现单点,网路问题时能够继续事务,提交了可用性。
缺点
- 性能比较差:3PC的事务处理延时也增加了1个RTT,变为3个RTT(propose+precommit+commit)。
- 数据不一致:参与者在接受到precommit之后,出现网络分区,继续提交事务,必然可能导致数据不一种,