MYSQL中的分库分表及产生的分布式问题

分库分表是分布式数据库架构中常用的优化手段,用于解决单库单表数据量过大、性能瓶颈 等问题。其核心思想是将数据分散到多个数据库(分库)或多个表(分表)中,以提升系统的吞吐量、查询性能可扩展性

一:为什么要分库分表

MySQL单库数据量超过5000万或单表数据量超过1000万时,性能会显著下降。随着数据增长,单库单表的查询和写入效率逐渐成为系统瓶颈。

二:拆分类型

拆分类型可分为两类:水平拆分和垂直拆分。

1.水平拆分

水平拆分又分为水平分库和水平分表。

**1)水平分库:**将相同表结构的表复制到另一个库中,减少单个数据库的访问压力。

优点

  • 提升系统吞吐量:大幅降低单库数据量,提升查询和写入性能;
  • 便于扩展**:**支持数据库层面的水平扩展(增加数据库节点)。
  • 提高可用性**:**单个数据库故障不会影响整体服务,其他库仍可正常访问。

缺点

  • 跨库查询复杂:需要聚合多个库的数据时,需借助中间件或手动处理,性能较低。
  • 事务一致性难保证:分布式事务实现复杂,通常需引入额外机制。

**2)水平分表:**是将同一张表的数据分到多个表中,提高查询效率。

优点

  • 单表数据量可控:将大表拆分为小表,避免单表数据量过大导致的索引效率下降、查询变慢等问题。
  • 提高并发性能:不同分表可分散到不同磁盘或物理机,降低I/O争用。

缺点

  • 跨表查询麻烦:需合并多个分表结果,查询复杂。
  • 扩容复杂度高:后期调整分表数量时,需要进行数据迁移。

2.垂直拆分

垂直拆分又分为垂直分库和垂直分表。

1)垂直分库:将不同表分到不同库中,降低单机的访问瓶颈。

优点

  • 业务解耦:按业务维度拆分库,不同业务的数据独立存储,降低耦合度。
  • 资源隔离:不同库可部署在不同服务器,避免资源竞争(如CPU、内存、磁盘IO)。
  • 扩展性强:业务增长时可单独扩展特定库的硬件资源。

缺点

  • 跨库查询复杂:需通过接口或中间件(如ShardingSphere)实现跨库关联查询,开发复杂度高。
  • 事务一致性难保证:分布式事务(如Seata)引入的性能开销。

**2)垂直分表:**将一张表的不同列拆分到多个表中,比如将热点字段或者长度大的字段单独分表。

优点

  • 冷热数据分离:将高频字段与低频字段拆分,减少单表数据量,提升查询效率。
  • 减少锁冲突:不同业务字段拆分后,更新操作锁定更少数据。

缺点

  • 查询复杂:跨表查询需关联操作,增加开发复杂度;
  • 数据量大:仍需解决单表数据量过大问题。

三:分库分表策略

在选取分库分表的策略前,首先要了解什么是分片键。

分片键(Sharding Key) :决定数据分布的字段,需选择高频查询条件(如用户 ID、订单 ID),避免跨分片查询(尽量选取连续的分片放到同一个库或表中)。

1.常见的分片策略

1)哈希取模 :对分片字段进行哈希取模(shard_id = hash(key) % node_count)

优点:

  • 数据分布均匀,不会容易出现冷热数据分离导致性能瓶颈。

缺点:

  • 扩容时需迁移大量数据(如从 3 库扩至 4 库,需重新计算所有数据的分片)。
  • 会出现跨分片查询的情况(如要查询订单金额前10,需要查询每段分片的前10然后比较)。

2)范围划分:按时间(如年 / 月)或数值范围(如用户 ID>1000 万)分片,适合递增数据(如订单)。

优点:

  • 便于水平扩展,如果要进行扩容,只需要添加节点即可,无需像哈希取模一样要进行数据迁移。
  • 连续分片能够尽可能的避免跨分片查询,提高查询性能。

缺点:

  • 可能导致热点分片(如最新月份的数据量过大),会被频繁的读和写,从而导致单个分片的数据量访问过大,出现性能瓶颈。

四.分布式问题

**1.分布式主键:**分库分表后需保证不同库 / 表的主键唯一。

  • UUID:简单易用,但作为主键性能较差(字符串类型,索引效率低)。
  • 雪花算法(Snowflake):生成 64 位唯一整数,包含时间戳、机器 ID 等,性能高且有序,适用于高并发场景。
  • 数据库自增序列:每个分片设置不同的起始值和步长(如库 1 起始 1、步长 3;库 2 起始 2、步长 3),避免主键冲突。

**2.分布式事务:**分布式事务需要解决跨节点(如跨数据库、跨服务)操作的原子性问题,即确保多个节点的操作要么全部成功,要么全部回滚,下面主要讲解seata中的两种模式。

在讲解两种模式前需要了解三个概念。

  • TM(Transaction Manager):事务管理器
  • TC(Transaction Coordinator):事务协调者
  • RM(Resource Manager):资源管理器
特性 AT 模式(Auto Transaction) XA 模式
一致性级别 最终一致(柔性事务) 强一致(刚性事务)
业务侵入性 无侵入(基于生成回滚日志) 低侵入(需使用 Seata 提供的 XA 数据源)
性能损耗 较低(仅在提交 / 回滚阶段有少量额外开销) 较高(两阶段提交需等待所有分支事务响应)
隔离性 基于全局锁实现读已提交(RC) 支持可重复读(RR)等强隔离级别
适用场景 高并发、允许短暂不一致的业务(如电商订单、库存) 金融级强一致场景(如资金转账、账户余额)
数据库支持 关系型数据库(MySQL、Oracle 等) 支持 XA 协议的数据库(MySQL 5.7+、PostgreSQL)

1)AT模式

(1)一阶段(Prepare)

  • 注册分支事务
  • 生成回滚日志:将相关信息存入 UNDO_LOG 表。
  • SQL 执行并提交
  • 释放本地锁:本地事务提交,释放数据库行锁。

(2)二阶段(Commit/Rollback)分为提交和回滚两种情况

  • 提交(Commit):TM(事务管理器)通知 RM(资源管理器)直接删除 UNDO_LOG,无需操作数据库。
  • 回滚(Rollback):RM 通过 UNDO_LOG 中的记录恢复数据。

2)XA模式(两阶段提交模式)

XA 模式基于数据库原生 XA 协议实现强一致事务,遵循"两阶段提交(2PC)" 协议:

(2)一阶段(Prepare)

  • TM 向所有 RM 发送prepare请求。
  • RM 执行本地事务,但不提交,将事务资源锁定。
  • RM 向 TM 返回成功失败

(2)二阶段(Commit/Rollback)

  • 若所有 RM 均返回成功,TM 发送commit,RM 提交本地事务;
  • 若任一 RM 失败,TM 发送rollback,RM 回滚本地事务。

五.Seata 中如何配置?

(一)AT 模式配置示例(基于 Spring Boot)

java 复制代码
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: my_test_tx_group
  config:
    type: nacos  # 配置中心类型
    nacos:
      server-addr: 127.0.0.1:8848
  registry:
    type: nacos  # 注册中心类型
    nacos:
      server-addr: 127.0.0.1:8848
  data-source-proxy-mode: AT  # 指定AT模式

关键步骤

  1. 引入 Seata 客户端依赖;
  2. 配置数据源代理(DataSourceProxy);
  3. 在需要分布式事务的方法上添加@GlobalTransactional注解。

(二)XA 模式配置示例

java 复制代码
seata:
  data-source-proxy-mode: XA  # 指定XA模式
  xa-override-boundary: true  # 允许XA事务跨越多个本地事务

关键步骤

  1. 使用 Seata 提供的SeataDataSourceProxyXA包装数据源;
  2. 确保数据库开启 XA 支持(如 MySQL 需设置innodb_support_xa=ON);
  3. 其余配置与 AT 模式类似。

六.总结

维度 AT 模式 XA 模式
事务协调机制 基于 UNDO_LOG 和全局锁 基于数据库 XA 协议
资源锁定时间 仅在一阶段执行期间锁定(时间短) 一阶段到二阶段提交期间一直锁定(时间长)
性能 高(接近本地事务) 低(两阶段提交开销大)
回滚机制 自动根据 UNDO_LOG 回滚 依赖数据库回滚能力
隔离级别 读已提交(RC) 可重复读(RR)等数据库原生级别
异常处理 需处理全局锁冲突和补偿失败 需处理事务悬挂和协调者故障
  • AT 模式是 Seata 的默认模式,适合大多数高并发、最终一致的业务场景,通过无侵入的方式实现柔性事务。
  • XA 模式适合对一致性要求极高的金融级业务,依赖数据库原生支持实现强一致,但性能较低。
  • 实际应用中,建议根据业务特性混合使用不同模式(如核心链路用 XA,例如转账等功能,非核心用 AT),并结合监控系统及时发现和处理异常。
相关推荐
岁岁种桃花儿14 小时前
MySQL从入门到精通系列:InnoDB记录存储结构
数据库·mysql
jiunian_cn15 小时前
【Redis】hash数据类型相关指令
数据库·redis·哈希算法
冉冰学姐16 小时前
SSM在线影评网站平台82ap4(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm框架·在线影评平台·影片分类
Exquisite.16 小时前
企业高性能web服务器(4)
运维·服务器·前端·网络·mysql
知识分享小能手17 小时前
SQL Server 2019入门学习教程,从入门到精通,SQL Server 2019数据库的操作(2)
数据库·学习·sqlserver
踩坑小念18 小时前
秒杀场景下如何处理redis扣除状态不一致问题
数据库·redis·分布式·缓存·秒杀
萧曵 丶18 小时前
MySQL 语句书写顺序与执行顺序对比速记表
数据库·mysql
Wiktok19 小时前
MySQL的常用数据类型
数据库·mysql
曹牧19 小时前
Oracle 表闪回(Flashback Table)
数据库·oracle
J_liaty19 小时前
Redis 超详细入门教程:从零基础到实战精通
数据库·redis·缓存