MySQL分库分表架构设计:从问题分析到解决方案
Executive Summary
核心观点(金字塔原理)
结论先行: 分库分表是解决MySQL单机IO/CPU瓶颈的核心架构手段,需根据具体瓶颈类型选择水平或垂直拆分策略。
支撑论点:
- IO瓶颈(磁盘IO、网络IO)通过分库和垂直分表解决
- CPU瓶颈(SQL复杂度、单表数据量)通过SQL优化和水平分表解决
- 四种分库分表策略各有适用场景,需结合业务特点选择
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增加节点方案处理?