分布式事务(CAP/BASE/XA/TCC/MQ)
2021-02-25 23:37:40 5 举报
AI智能生成
分布式事务(CAP/BASE/XA/TCC/MQ)
作者其他创作
大纲/内容
理论
CAP协议
概念
一致性(Consistency)
可用性(Availability)
分区容错性(Partition Tolerance)
权衡
AP
保证高可用,牺牲强一致性,退而求其次保证最终一致性(主流方案)
CP
牺牲可用性,保证各分区间的强一致性,数据没有完全同步的情况下不对外提供服务(zookeeper)
BASE协议
概念
基本可用(Basically Available)
软状态(Soft State)
最终一致性(Eventually Consistent)
核心思想
其实是对AP的完善,即使无法做到强一致性,但可以根据自身业务特点,采用适当的方式达到最终一致性
XA模式
2PC:两阶段提交
概括
一般是由参与者和协调者组成,分为两阶段
第一阶段就是准备,冻结一些资源,第二阶段就是提交或者回滚
存在的问题很明显
单点故障:协调者挂了,参与者会一直阻塞下去
同步阻塞:资源锁需要等到两阶段结束后才释放,性能较差
数据不一致:协调者发出的请求可能由于网络原因得不到响应
细节
投票 prepare
事务管理器给每个参与者发送prepare消息,让其执行本地事务,记录日志,此时事务没有提交
记录日志
undo log:记录修改前的数据,用于数据回滚
redo log:记录修改后的数据,用于事务提交后写入数据文件
commit/rollback
如果所有参与者的本地事务都执行成功了,则commit提交事务
如果其中有一个或者多个参与者执行失败或者超时,则rollback回滚事务
3PC:三阶段提交
改进
把两阶段提交的投票阶段一分为二,加入了一个预提交的缓冲阶段(先询问,再锁资源)
同时在协调者和参与者中都引入超时机制
优点:解决了单点问题,减少阻塞
参与者无法及时收到协调者的信息后,会默认执行commit
缺点:依然不能解决数据一致性问题
没有收到的协调者消息有可能是回滚
TCC模式
柔性事务
解决方案
解决方案
理论
预处理(Try)
主要是做业务检测以及资源预留(冻结库存)
确认(Confirm)
(Try 都成功了)
(Try 都成功了)
确认提交,Try阶段所有分支事务执行成功后,开始执行Confirm
只要Try成功,则Confirm一定成功,如果出错则进行重试或人工处理
撤销(Cancel)
(Try 有失败)
(Try 有失败)
在Try阶段业务执行错误的情况下执行回滚,预留资源的释放
通常认为Cancel也是一定成功的,如果失败则进行重试或者人工处理
实现
tcc-transaction
https://github.com/changmingxie/tcc-transaction
star 4.9k
Hmily
https://github.com/dromara/hmily
star 3.4k
ByteTCC
https://github.com/liuyangming/ByteTCC
star 2.5k
EasyTransaction
https://github.com/QNJR-GROUP/EasyTransaction
star 2.2k
其他方案
支付宝 GTS
蚂蚁金服 Fescar
TCC需要注意的
三种异常处理
三种异常处理
空回滚
问题:分支事务所在服务器宕机或网络异常,此时没有执行Try,当故障恢
复后,会调用Cancel接口执行回滚,如何判断是空回滚还是正常回滚?
复后,会调用Cancel接口执行回滚,如何判断是空回滚还是正常回滚?
解决:增加一张分支事务记录表,其中包含全局事务 ID 和分支事务 ID,在
第一阶段 Try 方法里插入一条记录,表示一阶段执行了,Cancel接口中读取
该记录,如果存在记录,则正常回滚,如果不存在,则是空回滚
第一阶段 Try 方法里插入一条记录,表示一阶段执行了,Cancel接口中读取
该记录,如果存在记录,则正常回滚,如果不存在,则是空回滚
悬挂
问题:RPC调用分布式事务Try方法时,由于网络原因发生拥堵,通常RPC调用
是有超时时间的,超时以后TM就通知RM回滚资源,回滚完成后Try方法才执行
即:Cancel发生在Try之前,业务资源预留后没有办法处理怎么办?
是有超时时间的,超时以后TM就通知RM回滚资源,回滚完成后Try方法才执行
即:Cancel发生在Try之前,业务资源预留后没有办法处理怎么办?
解决:分支事务记录表中如果记录了二阶段已经执行过,则Try方法不再执行
幂等
问题:Confirm和Cancel失败需要进行重试,如何保证幂等?
解决:分支事务记录表中维护执行状态,每次执行前都查询该状态
TCC与XA对比
XA是资源层面的分布式事务,强一致性,在两阶段提交的整个过程中,一直持有资源的锁
TCC是业务层面的分布式事务,最终一致性,降低锁粒度,不会一直持有资源的锁
Seta
消息队列
可靠消息最终
一致性方案
一致性方案
事务发起者执行完本地事务后,发出一条消息,事务参与者一定能接收到消息并处理成功
借助消息中间件完成
面临的问题
本地事务与消息发送的原子性问题
本地事务+定时轮询
事务参与者接收消息的可靠性
重试/ack机制
消息重复消费的问题
参与者接口幂等
实现
本地消息表方案
原子性
发送方在信息入库的同时维护一张消息记录表
通过本地事务保证两张表的数据一致
可靠性
使用定时任务轮询消息记录表的状态进行异步发送
消费者开启基于MQ的消息确认机制(ack)
缺点:定时轮询扫描数据库,对性能有影响,不推荐
RocketMQ方案
4.3之后的版本
支持事务消息
4.3之后的版本
支持事务消息
执行流程
消息生产者发送事务消息到 MQ Server,MQ Server回应消息发送成功
生产者开始执行本地事务,如果执行失败则通知 MQ Server 回滚,删除记录
如果生产者的本地事务执行成功,则 MQ Server 将消息发送给消费者
消费者开启 ack 消息确认机制,成功则通知 MQ Server,失败则重试
如果生产者执行本地事务时超时或者挂掉怎么办?
RocketMQ 提供了事务回查机制
最大努力通知方案
A系统本地事务执行完成后发送消息到MQ,MQ通知B系统执行事务,如果B失败了则重试,尝试N次后还是不成功则放弃
允许少数事务失败,一般用在对分布式事务要求不严格的情况下,比如记录日志或者状态等
0 条评论
下一页