⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/6933003178661462023 「小泥洼」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

前言

通过对数据的垂直拆分或水平拆分后,我们解决了数据库容量、性能等问题,但是将会面临数据迁移和数据一致性的问题。

在数据迁移方面,需要考虑如何快速迁移、平滑迁移、不停机的迁移等。待数据迁移完毕后,还需要校验数据的完整性。

数据一致性方面,要根据的业务来判断是否要必要引入分布式事务,如果需要引入分布式事务,需要斟酌是采用XA,还是基于BASE的柔性事务。

数据迁移

数据迁移是很容易出故障的一个环节,需要考虑怎么更加平滑的迁移旧数据到新的数据库和系统,以及达到数据准确、快速迁移、减少停机、对业务的影响小等,特别是异构的数据结构情况下,难度更大。

全量

全量迁移的过程如下:

  • 业务系统停机。
  • 数据库迁移,校验数据一致性。
  • 然后业务系统升级,接入新的数据库。

缺点:

  • 需要业务系统停机
  • 迁移时间较长,对业务影响较大。如果是异构数据的话,需要使用程序来处理,迁移时间更长。

全量+增量

全量+增量迁移的方式,需要依赖数据本身的创建时间,步骤如下:

  • 先同步数据到最近的某个时间戳(创建时间)。
  • 然后发布系统升级维护的通知。
  • 然后同步最近一段时间变化的数据。
  • 最后升级系统,接入新的数据库。

全量+增量的同步相比全量同步的方式,大大的减少了系统停机的时间,对业务影响较小。

binlog+全量+增量

binlog+全量+增量是通过从数据库的主库或者从库解析和重新构造数据,实现复制。

通常情况下都需要中间件等工具的支持,一般需要中间件等工具的支持。可以实现多线程、断点续传、全量和增量数据的同步,还可以实现自动扩容和缩容。

常见的工具有:Canal、ShardingSphere-scaling等

分布式事务

XA分布式事务

XA分布式事务,是数据库本身支持的协议,具备强一致性。

XA分布式事务的组件:

  • 应用程序(Application Program, 简称AP): 用于定义事务边界,即事务的开始和结束,并且在事务边界内对资源进行操作。
  • 资源管理器(Resource Manager, 简称RM): 如数据库、文件系统,并且提供访问资源的方式。
  • 事务管理器(Transaction Manager, 简称TM): 负责分配事务唯一标识,监控事务的执行进度,并且负责事务的提交、回滚等。

XA接口:

  • xa_start 负责开启或者恢复一个事务分支
  • xa_end 负责取消当前线程与事务分支的关联
  • xa_prepare 询问RM是否准备好提交事务分支
  • xa_commit 通知RM提交事务分支
  • xa_rollback 通知RM回滚事务分支
  • xa_recover 需要恢复的XA事务

MySQL从5.0.3开始支持InnoDB引擎的XA分布式事务。

完整的XA事务处理流程如下:

主流的XA框架有:Atomikos、Narayana、Seata

XA分布式事务存在的问题:

  • 同步阻塞:全局事务包含了多个独立的事务分支,这一组事务分支要么都不成功,要不都失败,各个分支的ACID特性共同构成了全局事务的ACID特性。如果对读操作很敏感,需要将数据库的隔离级别设置为SERIALIZABLE,性能特别的差。
  • 单点故障:TM存在单点故障,需要考虑TM高可用性。
  • 数据不一致:极端情况下,会出现事务失败问题,需要监控和人工处理。即二阶段commit请求后,发送网络故障,只有一部分RM收到请求,其他节点没有收到Commit请求的情况。

柔性事务

BASE的核心在于,保证系统基本可用的前提下,通过利用柔性状态(支付操作后不是支付成功,而是支付中状态),实现数据的最终一致性,如下:

  • 基本可用(Basically available),分布式事务参与方不一定同时在线。
  • 柔性状态(Soft state), 允许系统状态更新有一定的延迟,出现一些中间状态,这个延迟对客户来说不一定能够察觉。
  • 最终一致性(Eventually consistent),通常是通过消息传递的方式保证系统的最终一致性。

柔性事务核心理念是通过业务逻辑将互斥锁操作从RM层上升到业务层,通过放宽对强一致性的要求,来换取系统吞吐量的提升。

BASE柔性事务常见模式

  • TCC: 通过手动补偿处理
  • AT: 通过自动补偿处理

TCC介绍

TCC模式即将每个服务业务操作分成两个阶段,第一个阶段检查并预留相关资源,第二个阶段根据所有服务业务的try状态来操作,如果都成功,则进行Confirm操作,如果任意一个Try发送错误,则全部Cancel。

  • Try:准备操作,完成所有的业务检查,预留业务资源。
  • Confirm:真正执行的业务逻辑,不做任意的业务检查,只使用Try阶段预留的业务资源。因此Try操作成功,Confirm必须能成功。同时,Confirm操作必须保证冥等性,保证一笔分布式事务能切只能成功一次。
  • Cancel:释放Try阶段预留的业务资源,同样Cancel操作也必须满足冥等性。

TCC模型实际是通过业务分解来实现分布式事务,对业务有较强的侵入性。

TCC模型需要注意的地方:

  • 允许空回滚,即try没有完成资源预留,允许短路操作。
  • 防悬挂控制,即需要保证,cancel必须在try之后才执行。
  • 冥等性设计,即需要保证confirm和cancel需要保证冥等性,防止网络因素导致数据混乱。

AT

AT模式就是两阶段提交,自动生成反向SQL,当发生异常的时候,通过反向SQL回滚数据。

Seata框架对AT的支持如下:

  • 第一阶段,业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
  • 第二阶段,提交异步化,非常快速的完成,回滚的话通过一阶段的回滚日志进行反向补偿。

柔性事务下的事务特性

  • 原子性:正常情况下保证

  • 一致性:某个时间点,数据存在不一致,但是最终是一致的。

  • 隔离性:某个时间点,A能读到B事务未提交的结果,即会脏读现象。

  • 持久性:和本地事务一样,只要commit则数据就会被持久化。

总结

分布式事务主要目的是解决数据一致性问题,XA强一致,但是吞吐量太低,不利于高并发场景。柔性事务不保证强一致性,但是通过补偿实现最终一致性,常见的补偿有重试补偿、调度补偿、人工补偿等。

文章目录
  1. 1. 前言
  2. 2. 数据迁移
  3. 3. 分布式事务
    1. 3.0.0.1. XA分布式事务
    2. 3.0.0.2. 柔性事务
  • 4. 总结