MySQL分库分表架构设计:从问题分析到解决方案

Executive Summary

核心观点(金字塔原理)

结论先行: 分库分表是解决MySQL单机IO/CPU瓶颈的核心架构手段,需根据具体瓶颈类型选择水平或垂直拆分策略。

支撑论点:

  1. IO瓶颈(磁盘IO、网络IO)通过分库和垂直分表解决
  2. CPU瓶颈(SQL复杂度、单表数据量)通过SQL优化和水平分表解决
  3. 四种分库分表策略各有适用场景,需结合业务特点选择

SWOT 分析

维度 分析
S 优势 有效解决单机性能瓶颈;成熟的中间件支持(ShardingSphere、Mycat、TDDL);可按需选择拆分粒度
W 劣势 引入分布式事务复杂性;跨库查询性能下降;主键全局唯一性需额外处理
O 机会 高并发大数据量业务场景;结合ES解决跨库查询问题;服务化拆分契合微服务架构
T 威胁 扩容迁移复杂度高;非partitionKey查询效率低;运维复杂度显著增加

适用场景

  • 单表数据量过大导致SQL效率下降(水平分表)
  • 系统并发量高,单库IO/CPU压力大(水平分库)
  • 业务模块解耦,按领域拆分(垂直分库)
  • 表字段多且冷热数据分明(垂直分表)

问题 & 解决方案

IO瓶颈

  • 磁盘IO:大量慢SQL
    • 解决方案:分库,垂直分表
  • 网络IO
    • 解决方案:分库

CPU瓶颈

  • SQL问题,比如SQL中有join,group by等,条件查询多,函数多,增加CPU运算
    • 解决方案:SQL优化,建立合适的索引,service中运算;索引注意最左匹配原则
  • 单表数据量太大,扫描行多,SQL效率低
    • 解决方案:水平分表

水平分表

  • 按照某一字段一定的路由规则(hash,range等),将一个表的数据拆分到N个表中
  • 结果:表结构一致,数据没有交集,所有表数据并集为全量数据
  • 场景:系统并发量较小,只是单表数据量太大,影响SQL效率,CPU成为瓶颈。表数据量小了,SQL效率提高,CPU负担小;

水平分库

  • 按照某一字段一定的路由规则(hash,range等),将一个库的数据拆分到N个库中
  • 结果:库结构一致,数据没有交集,所有库数据并集为全量数据
  • 场景:系统并发量较高,分表不能解决问题,IO/CPU压力较大时,可以采用此方案

垂直分库

  • 一般以大表为依据,按照业务归属不同,拆分到不同的库中
  • 结果:库结构不一样,库数据不一样,没有交集,所有库并集为全量数据。
  • 场景:可以理解为服务化

垂直分表

  • 以字段为依据,将字段拆分不同的表中,比如冷热数据拆分,主/次表
  • 结果:表结构不一样,一般至少有一列交集一般为主键,用于关联数据,所有表数据并集为全量数据
  • 场景:系统绝对并发量并没有上来,表的记录并不多,但是字段多,并且热点数据和非热点数据在一起,单行数据所需的存储空间较大。以至于数据库缓存的数据行减少,查询时会去读磁盘数据产生大量的随机读IO,产生IO瓶颈。可以理解为列表页和详情页的关系

工具

  • sharding-sphere:jar,前身是sharding-jdbc;
  • TDDL:jar,Taobao Distribute Data Layer;
  • Mycat:中间件。
  • spring提供的分库方案

分库分表引入的问题

  • 主键全局唯一问题?雪花算法?
  • 非partitionKey的查询问题
    • 解决方案:ES
  • 非partitionKey跨库表分页查询问题
    • 解决方案:ES
  • 扩容问题
    • 双写?Redis增加节点方案处理?