前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式事物的设计与实践

分布式事物的设计与实践

作者头像
彼岸舞
发布2021-04-01 09:53:34
4500
发布2021-04-01 09:53:34
举报
文章被收录于专栏:java开发的那点事

分布式事物设计与实践

数据一致性定义

  • 任何人
  • 任何时间
  • 任何地点
  • 任何接入方式
  • 任何服务
  • 数据都是一致的

数据不一致产生的原因

  • 数据分散在多处
    • 多个DB
    • DB和缓存
  • 二手交易平台案例
    • 用户,交易,商品等功能

分布式事物产生的原因

刚开始是一个单体进程

经过演变,单体式服务演变成微服务,每个服务都是单独的进程

在用户请求量大的时候,为了缓解数据库的压力,添加了分布式缓存

分布式事物案例

电商平台购买商品

下单->减库存->支付

这就是分布式事物问题,当APP要买东西,这个操作会涉及到多个服务,意味着要操作多个数据库,这样本地事物就无法保证数据的一致性,所以就产生了分布式事物问题.

分布式事物场景

  • 电商下单场景
    • 下单
    • 发送消息到MQ
  • 一致性保证
    • 本地事物
      • 下单操作
      • 发送MQ消息操作
      • 放进一个本地事物

上述做法有什么问题?

问题:如果发送消息超时了,你是不知道MQ的返回结果是成功和失败的,,timeout这操作不是一个原子的

分布式事物分类

  • 刚性分布式事物
    • 强一致性
    • XA模型
    • CAP
      • CP
  • 柔性分布式事物
    • 最终一致性
    • CAP,BASE理论
      • AP

刚性分布式事物

满足传统事物特性

ACID( Atomicity-原子性, Consistency-一致性,Isolation-隔离性,Durability-持久性)

XA模型

  • XA是X/Open CAE Specification(Distributed Transaction Processing)模型中定义,XA规范由AP,RM,TM组成
  • 其中应用程序(Application Program简称AP),AP定义事物边界(定义事物开始和结束)并访问边界事物内的资源
  • 资源管理器(Resource Manager简称RM),RM管理计算机共享的资源,资源及数据库等
  • 事物管理器(Transaction Manager,简称TM),负责管理全局事物,分配事物唯一标识,监控事物的执行进度,并负责事物的提交,,回滚,失败恢复等

2PC(两阶段提交-XA规范标准实现)

  • 案例
    • 组织爬山
  • 过程
    • 二阶段提交,是XA规范的标准实现
    • TM发起prepare投票
    • RM都同意后,TM再发起Commit
    • Commit 过程出现宕机等异常,节点服务重启后,根据XA recover 再次进行commit补偿
  • 缺点
    • 同步阻塞模型
    • 数据库资源锁定时间过长
    • 全局锁(隔离级别-串行化),并发低
    • 不适合长事物场景

柔性分布式事物

  • CAP
    • 分布式环境下P一定需要,CA权衡折中
  • BASE理论
    • Basically Available-基本可用
    • Soft state 柔性状态
    • Eventual consistency 最终一致性
  • 架构思考
    • 柔性事物是对XA协议的妥协,他通过降低强一致性要求,从而降低数据库资源锁定时间,提升可用性
  • 架构经典实现
    • TCC模型
    • Saga模型

TCC模型

  • Try-confirm-cancel
  • TCC模型完全交由业务实现,每个子业务都需要实现Try-Confirm-cancel接口,对业务侵入大
    • 资源锁定交由业务方
  • try
    • 尝试执行业务,完成所有检查,预留必要的业务资源
  • confirm
    • 真正执行业务,不再做业务检查
  • Cancel
    • 释放Try阶段预留的业务资源
  • 案例
    • 汇款服务,收款服务案例
      • A用户向B用户汇款500元
    • 汇款服务
      • try
        • 检查A账户的有效性,及查看A账户的状态是否为"转账中"或者"冻结"
        • 检查A账户余额是否充足
        • 从A账户中扣减500元,并将状态设置为转账中
        • 预留扣减资源,将从A往B账户转账500元这个事件存入消息或者日志中
      • confirm
        • 不做任何操作
      • cancel
        • A账户增加500元
        • 从日志或者消息中,释放扣减资源
    • 收款服务
      • try
        • 检查B账户是否有效
      • confirm
        • 读取日志或消息,B账户增加500元
        • 从日志或者消息中,释放扣减资源
      • cancel
        • 不做任何操作

Saga模型

  • 起源于1987年Hector & Kenneth发表的论文Sagas
  • Saga模型把一个分布式事物拆分为多个本地事物,每个本地事物都有相应的执行模块和补偿模块(对应TCC中的confirm和cancel)
  • 当Saga事物中任意一个本地事物出错时,可以通过调用相关的补偿方法恢复之前的事物,到达事物最终一致性
  • 当每个Saga子事物T1,T2,....TN都有对应的补偿定义C1,C2,....CN-1,那么Saga系统可以保证
    • 子事物序列T1,T2,.....TN得以完成(最佳情况)
    • 或者序列T1,T2,...TJ,CJ-1,..., C2,C1,0<J<N,得以完成
  • Saga隔离性
    • 业务层控制并发
      • 在应用层加锁
      • 应用层预先冻结资源等
  • Saga恢复方式
    • 向后恢复,补偿所有已完成的事物,如果任意子事物的失败
    • 向前恢复,重试失败的事物,假设每个子事物最终都会成功

刚性分布式事物VS柔性分布式事物

刚性事物(XA)

柔性事物

业务改造

回滚

支持

实现补偿接口

一致性

强一致(CP)

最终一致性(AP)

隔离性

原生支持

实现资源锁定接口

并发性能

严重衰退

略微衰退

适合场景

短事物,并发较低

长事物,高并发

我们如何实践

  • 问题通用解决思路
    • 解决这个问题本身
    • 让问题本身消失
      • 圆珠笔笔芯漏油解决
  • 圆珠笔笔芯在写2W次就开始漏油,如果要解决这个问题本身,那么就是加入更好的材料,更高端的技术,如果是让问题本身消失呢,就是固定一个次数,让它只能写1.5W次就没油开始丢弃,这样的两种办法
  • 首选是让问题本身消失,次选是解决这个问题本身
  • 方案一:从业务场景消除分布式事物
    • 思路:核心业务先处理,其他业务异步处理
  • 方案二:柔性分布式事物

柔性分布式事物实践

  • 通用处理思路
    • 本地事物-->短事物
    • 分布式事物-->长事物
    • 转变成多个短事物
    • 案例
      • A[下单]->B[减库存]->C[支付]
        • A->DB1
        • B->DB2
        • C->DB3
        • A/B/C都成功
        • A/B成功,C失败
          • 补偿
  • 业务场景
    • 异步场景
      • 基于MQ消息驱动分布事物
    • 同步场景
      • 基于异步补偿分布

异步场景分布式事物设计

异步场景

商品交易

下单,支付

方案一:业务方提供本地操作成功回查功能
  • 事物消息:MQ提供类似X/Open XA的分布式事物功能,通过MQ事物消息能达到分布式事物的最终一致
  • 半消息:暂不投递的消息,发送方已将消息成功发送到了MQ服务端,但是服务端未收到生产者对该消息的二次确认,此时该消息被标记成"暂不能投递"状态,处于该种状态下的消息即半消息
  • 消息回查:由于网络闪断,生产者应用重启等原因,导致某条事物消息的二次确认丢失,MQ服务端通过扫描发现某条消息长期处于半消息时,主要主动向消息生产者询问该消息的最终状态(Commit或Rollback),即消息回查
  • MQ分布式事物设计方案

  • MQ分布式事物消息设计
    • MQ事物消息设计事物消息作为一种异步确保型事物,将两个事物分支通过MQ进行异步解耦,MQ事物消息的设计流程同样借鉴了两阶段提交理论,整体交互流程如上图
    1. 事物发起方首先发送prepare消息到MQ
    2. 在发送prepare消息成功后执行本地事物
    3. 根据本地事物执行结果返回commit或rollback
    4. 如果消息是rollback,MQ将删除该prepare消息,不进行下发,如果是commit消息,MQ会将消息发送给consumer端
    5. 如果执行本地事物过程中,执行端挂掉,或者超时,,MQ服务器端将不停的询问producer来获取事物状态
    6. consumer端的消费成功机制有MQ保证
  • 成本:
    • MQ需要支持半消息
    • MQ需要提供消息遍历
    • 业务方需要提供回查接口
  • 业务方接入步骤

  • 优点
    • 通用
  • 缺点
    • 业务方需要提供回查接口,对业务侵入大
    • 发送消息非幂等
    • 消费端需要处理幂等
方案二:本地事物消息表
  • 本地操作和发送消息通过本地事物强一致性
    • 本地事物操作表
    • 本地事物消息表
      • mqMessages(msgid,content,topic,status)

  • 发送端消息不幂等
    • At least once (最少发一次)
    • Once Only (只发一次)
    • At more once(最多发一次)
  • 消费端处理消息幂等
    • 分布式锁
  • A->B->C
    • A/B成功,C失败
      • 记录错误日志
      • 报警
      • 人工介入
  • 优点
    • 业务入侵小

相比于提供消息回查接口(RockectMQ)来说,实际异步场景还是本地消息事物表使用的比较多

同步场景分布式事物设计

  • 同步场景
    • 首页推荐商品列表
      • 商品信息
      • 用户信息
      • 社交信息
    • 购买商品
      • 下单->A
      • 减库存->B
      • 支付->C

通过业务逻辑层驱动

  • 解决方案
    • 基于异步补偿的分布式事物
    • 架构设计的三大关键点

开始记录调用请求的参数,如果失败后基于参数做补偿接口,接口需要保证幂等性

  • 总体架构设计

场景:A下单,B减库存,C支付,在调用接口的时候,A先走Proxy存入事物ID,状态,参数等信息,然后执行本地事物,接着B,C走同样的流程如果都成功,那么事物状态改成2,也就是成功,如果在C失败的时候可以更具参数,事物ID对A,B进行补偿

业务逻辑层Proxy设计(基于AOP实现)
  • 逻辑层调用上加上事物注解@Around("execution(**(..)) && @annotation(TX)")
  • Proxy在真正业务逻辑被调用之前,生成一个全局唯一TXID标示事务组,TXID保存在ThreadLocal变量中,方法开始前写入,完成后清除,并向远端数据库写入TXID并把事务组制成开始状态
  • 业务逻辑层调用数据访问层之前,通过RPCProxy代理记录,当前调用请求参数
  • 如果业务正常,调用完成后,当前方法的调用记录删除或者存档
  • 如果业务异常,查询调用链反向补偿
  • 数据访问层设计
    • 原子接口
    • 补偿接口
      • 谁来提供?
        • 业务方提供
      • 幂等性保证
        • 采用本地资源锁,锁定唯一资源
    • 基于原则接口方法,在方法名加注解标注补偿方法名
    • @Compensable(cancelMethod = "cancelRecord")
  • 分布式事物补偿服务
    • 事物组表(数据库表TDB)
      • 记录事物组状态
      • txid state timestamp
    • 事物调用组表(数据库表TDB)
      • 记录事物组内的每一次调用,以及相关参数
      • txid actionid callmethod pramatype params
    • 补偿策略
      • 调用执行失败,修改事物组状态
      • 分布式事物补偿服务异步执行补偿
分布式事物成功案例
  • 二手交易创建订单事务组正常流程
    • 锁库存->减红包->创建订单
  • 代理层透明记录调用请求参数
    • 记录事物域的开始与结束
    • 在所有远程调用成功时
    • 对业务逻辑不做侵入
分布式事物失败案例
  • 二手交易创建订单事务组异常流程
    • 微服务数据访问层失败,代理更改事务组状态
    • 微服务业务正常执行
    • 事物补偿服务异步执行补偿

好了,到这里分布式事物也就写完了..休息一下,,哎,又到了找工作的时候了,有需要可以联系我

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分布式事物设计与实践
    • 数据一致性定义
      • 数据不一致产生的原因
        • 分布式事物产生的原因
          • 分布式事物案例
            • 分布式事物场景
              • 分布式事物分类
                • 刚性分布式事物
                  • 2PC(两阶段提交-XA规范标准实现)
                • 柔性分布式事物
                  • TCC模型
                  • Saga模型
                • 刚性分布式事物VS柔性分布式事物
                  • 我们如何实践
                    • 柔性分布式事物实践
                    • 异步场景分布式事物设计
                    • 同步场景分布式事物设计
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档