两阶段提交协定(2PC)
转账性能开发
一、需要背景:
某 T 日, 田小胖想往他乡的父母寄毕业后的第一笔工资,而后他乐不可支来到楼下 ATM 机,拿出了本人的工资卡,开始输金额,输明码 ……
二、交易链路 A->B->C
假如某转账接口蕴含三个局部,银行内转账接口蕴含三个步骤:第一步校验,第二步扣款,第三步转账。
- A 服务器专门实现第一步,客户身份验证、银行卡明码校验、注销转账记录等性能。
- B 服务器专门实现第二步,负责把田小胖工资卡的钱临时转到外部用于转账的账户。
-
C 服务器专门实现第三步,把钱转账到田小胖父母的储蓄卡账户。
田小胖操作 ATM 机,通过网络发送到某业务零碎,业务零碎接口调起 A、B、C 接口。
请问,假如你是开发这个接口的负责人,B 机器扣完款了,C 机器因为日志磁盘满导致 JVM 宕机,
你应该怎么做?
1、跑路
2、修生产数据把钱字段改过来,而后再把本人的银行卡账户加两个 0
3、跑去问架构师拿分布式事务解决方案三、两阶段提交协定
2PC,是计算机网络尤其是在数据库畛域内,为了使基于分布式系统架构下的所有节点在进行事务处理过程中可能放弃原子性和一致性而设计的一种算法。
通常,二阶段提交协定也被认为是一种一致性协定,用来保障分布式系统数据的一致性。
说人话,在实际层面,协定 = 算法 = 一堆程序,TCP 协定通过三次握手四次挥手保障牢靠连贯。
分布式系统通过 2PC 实现数据在不同节点的一致性。假如你 6 位密码保护的银行卡内有着 10.00 块钱,10.00 块钱存在 mysql 的金额表的 money 字段。mysql 有 10 机器正本。而后 2PC 就解决你的 10.00 块钱在这 10 台机器同步的问题。阶段一:提交事务申请
协调者组织各参与者对一次事务操作的投票表态过程,因而 PC 的阶段一也被称为“投票阶段”
- 事务询问:协调者向所有参与者发送事务内容,询问是否能够执行事务提交操作,并开始期待各参与者的相应
- 执行事务:各参与者节点执行事务操作,并将 Undo 和 Redo 信息记入事务日志
- 各参与者向协调者反馈事务询问的响应:
如果参与者胜利执行了事务操作,那么就反馈给协调者 YES 响应,示意事务能够执行;
如果参与者没有胜利执行事务,那么就反馈给协调者 NO 响应,示意事务不能够执行。
阶段二:执行事务提交
协调者会依据各参与者的反馈状况来决定最终是否能够进行事务提交操作。
失常状况下蕴含执行事务提交和事务中断两种状况。
执行事务提交
- 发送提交申请:协调者向所有参与者节点收回 Commit 申请
- 事务提交:参与者接管到 Commit 申请后,会正式执行事务提交操作,并在实现提交之后开释在整个事务执行期间占用的事务资源。
- 反馈事务提交后果:参与者在实现事务提交之后,向协调者发送 ACK 音讯。
-
4、实现事务:协调者承受到所有参与者反馈的 Ack 音讯后,实现事务。
中断事务
如果任何一个参与者向协调者反馈了 No 响应,或者期待超时之后,协调者无奈接管到所有参与者的反馈响应,那么就会中断事务。中断事务能够了解为分布式事务执行的异常情况解决,Client 端执行是 Rollback。
- 发送回滚申请:协调者向所有参与者节点收回 Rollback 申请。
- 事务回滚:参与者接管到 Rollback 申请后,会利用其在阶段一中的 Undo 来执行事务回滚操作,并在实现回滚之后开释在整个事务执行期间占用的资源
- 反馈事务回滚后果
参与者在实现事务回滚之后,向协调者发送 ack 音讯 - 中断事务:协调者接管到所有参与者反馈的 Ack 音讯后,实现事务中断。
-
四、2PC 的示意图
事务提交
事务中断
2PC 优缺点
- 长处:简略不便,可能保障分布式数据一致性
- 毛病:
1、同步阻塞:A、B、C 三个接口是顺序调用
(Java API 回环栅栏、CompleteFuture 可能优化这一问题)
2、单点问题: 协调者故障
3、脑裂:提交二阶段的过程会存在局部节点 commit 的状况,协调者故障,无奈回滚
4、容错,任一节点失败都会导致整个事务失败
参考文献:
《从 Paxos 到 Zookeeper 分布式一致性原理与实际.pdf》