MySQL数据库在互联网应用中,面对高并发和大数据量的挑战时,常采用分库分表策略来提升性能。以下是互联网常用的MySQL分库分表方案:
一、分库分表类型
1. 水平分库- 概念:以字段为依据,按照一定策略(如hash、range等),将一个库中的数据拆分到多个库中。
- 结果:
每个库的结构都一样;
每个库的数据都不一样,没有交集;
所有库的并集是全量数据。
- 场景:系统绝对并发量高,分表难以解决问题,且没有明显的业务归属来垂直分库。
- 分析:库数量增加,IO和CPU压力可成倍缓解。
2. 水平分表- 概念:以字段为依据,按照一定策略(如hash、range等),将一个表中的数据拆分到多个表中。
- 结果:
每个表的结构都一样;
每个表的数据都不一样,没有交集;
所有表的并集是全量数据。
- 场景:系统绝对并发量未上来,但单表数据量过多,影响SQL效率,加重CPU负担。
- 分析:表数据量减少,单次SQL执行效率提高,减轻CPU负担。
3. 垂直分库- 概念:以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。
- 结果:
每个库的结构都不一样;
每个库的数据也不一样,没有交集;
所有库的并集是全量数据。
- 场景:系统绝对并发量高,且可以抽象出单独的业务模块。
- 分析:可进一步服务化,如将公用配置表、字典表或相关业务表拆到单独的库中。
4. 垂直分表二、分库分表工具
- sharding-sphere:jar包,前身是sharding-jdbc。
- TDDL:jar包,Taobao Distribute Data Layer。
- Mycat:中间件。
三、分库分表步骤
- 评估:根据容量(当前容量和增长量)评估分库或分表个数。
- 选key:选择均匀分布的key。
- 分表规则:确定分表规则(如hash或range等)。
- 执行:一般采用双写方式执行。
- 扩容问题:尽量减少数据的移动。
四、分库分表问题及解决方案
1. 非partition key的查询问题- 端上除了partition key不止一个非partition key作为条件查询:
映射法:同上。
冗余法:冗余数据,建立多个索引表。
2. 非partition key跨库跨表分页查询问题- NoSQL法:使用NoSQL数据库(如ES)解决。
3. 扩容问题- 水平扩容库(升级从库法):
扩容是成倍的,通过增加从库来扩展容量。
- 水平扩容表(双写迁移法):
同步双写:应用配置双写,部署。
数据复制:将老库中的老数据复制到新库中。
数据校验:以老库为准校对新库中的老数据。
去掉双写:应用去掉双写,部署。
五、分库分表总结
- 明确瓶颈:分库分表前需明确数据库瓶颈所在,合理选择分库还是分表,水平还是垂直。
- 选key重要:选key既要考虑拆分均匀,也要考虑非partition key的查询。
- 规则简单:拆分规则越简单越好,以满足需求为前提。
六、分库分表示例
示例GitHub地址:
https://github.com/littlecharacter4s/study-sharding