分库分表
关键点
目标
- 解决容量问题
- 将整个节点的数据量变小,降低单节点写压力,提升整个系统的容量上限
实现:分布式数据库作为数据分片的集群提供服务。
- 指导原则:扩展立方体
- x-axis:建集群(水平;最简单,整体扩展)<== 全部数据
- y-axis:业务拆分(垂直;按需,子系统的扩展)<== 业务分类数据
- z-axis:数据分片(拆分数据;同类数据,不同扩展方式)<== 任意数据
数据库垂直拆分
- 拆库:一个数据库按不同业务处理能力拆分成不同数据库。
- 拆表:针对单表数据量过大(宽表)的情况进行拆分(一个主表 -> 一个核心表+多个子表)。
- 「优」数据库集群的性能和容量整体提升(并行数据处理能力提升),系统和数据复杂度降低。
- 「缺」管理复杂;对业务系统侵入性强;改造过程复杂,易出故障;拆分有上限。
- 步骤:梳理拆分范围,检查评估和重构影响到的服务;准备新的数据库集群复制数据;修改系统配置,上线。
数据库水平拆分
- 分库:数据放在不同库。
- 分表:数据放在不同表。
- 优:解决容量问题;对系统的影响小于垂直拆分。
- 缺:管理复杂;复杂 SQL 支持;数据迁移问题(扩缩容);一致性问题。
- 拆分建议:不建议分表。
- 每个 MySQL 实例上可以建虚拟的DB,类似于分表的效果。
工具:框架和中间件
- JAVA 框架层:TDDL,Apache ShardingShpere-JDBC
- 中间件层:处于业务系统和数据库中间,模拟数据库。
- ShardingSphere:一套开源的分布式数据库中间件解决方案组成的生态圈,提供标准化的数据分片、分布式事务、数据库治理;含3款产品:JDBC, Proxy, Sidecar。
- 引入成本比较:框架 < 中间件 < 分布式数据库/数据网格
分库分表导致的一致性问题
- solution:分布式事务
- 一致性要求:在分布式条件下,多个结点的整体事务一致性。
- 场景要求一:严格的一致性————solution:数据库支持XA协议。
- 场景要求二:准实时/非实时的处理————solution:不用事务 or 使用柔性事务框架。
- solution 1:XA 分布式事务
- 一致性要求:强一致性
- 需要数据库对 XA 事务的支持。
- 模型
- AP, Application Program:由应用程序发起事务。
- RM, Resource Manager:多个,管理具体资源(如数据库)。
- TM, Transaction Manager:事务管理器;通知资源,控制协调本地事务提交/回滚。
- JAVA 中的分布式事务框架:Atomikos, JBOSS Naratana, Seata(支持 TCC / AT).
- 问题
- 同步阻塞问题
- 单点故障
- 数据不一致
- solution 2:BASE 柔性事务(Basically Avaiable, Soft State, Eventually Consistent)
- 一致性要求:最终一致性
- 适合场景:长事务 & 高并发
- 模式
- TCC / SAGA:手动补偿。TCC 模式三段逻辑都是独立的事务(准备操作 Try,确认操作 Commit,取消操作 Cancel);SAGA 无 Try 阶段,直接提交事务。
- AT:自动补偿;两阶段提交。
- 事务的发展:本地事务 -> XA(二阶段)强一致性事务 -> BASE 最终一致性事务
经验认识
数据迁移:新系统与老数据(异构数据迁移易出故障)
- 方式一:全量
- 优:简单
- 缺:停机时间随数据量上升,对业务影响较大
- 方式二:全量 + 增量(所有库表都有时间戳及状态字段)
- 优:停机时间较短
- 缺:数据库主库的读压力
- 方式三:全量 + 增量 + binlog
- 需要中间件支持:模拟从库,订阅读取 binlog,拿到数据,写入集群
- 历史数据:历史 binlog,全量
- 实时增量数据:主库正在执行的,增量
- 优:无需额外寻找增量的时间点,无需去主库读数据;平滑迁移,新老数据库可并行使用;可实现多线程断点续传,并发数据同步;可实现自定义复杂异构数据结构;可实现自动扩缩容。
- 需要中间件支持:模拟从库,订阅读取 binlog,拿到数据,写入集群
- 中间件工具:ShardingSphere-Scaling(模拟MySQL从库)
- 支持数据全量和增量同步
- 支持断点续传和多线程数据同步
- 支持数据库异构复制和动态扩容
- 可视化配置