MySQL数据库之互联网常用分库分表方案

MySQL数据库之互联网常用分库分表方案
最新回答
紫烟轻娆

2024-03-31 20:40:15

MySQL数据库在互联网应用中,面对高并发和大数据量的挑战时,常采用分库分表策略来提升性能。以下是互联网常用的MySQL分库分表方案:

一、分库分表类型

1. 水平分库
  • 概念:以字段为依据,按照一定策略(如hash、range等),将一个库中的数据拆分到多个库中。
  • 结果

    每个库的结构都一样;

    每个库的数据都不一样,没有交集;

    所有库的并集是全量数据。

  • 场景:系统绝对并发量高,分表难以解决问题,且没有明显的业务归属来垂直分库。
  • 分析:库数量增加,IO和CPU压力可成倍缓解。

2. 水平分表
  • 概念:以字段为依据,按照一定策略(如hash、range等),将一个表中的数据拆分到多个表中。
  • 结果

    每个表的结构都一样;

    每个表的数据都不一样,没有交集;

    所有表的并集是全量数据。

  • 场景:系统绝对并发量未上来,但单表数据量过多,影响SQL效率,加重CPU负担。
  • 分析:表数据量减少,单次SQL执行效率提高,减轻CPU负担。
3. 垂直分库
  • 概念:以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。
  • 结果

    每个库的结构都不一样;

    每个库的数据也不一样,没有交集;

    所有库的并集是全量数据。

  • 场景:系统绝对并发量高,且可以抽象出单独的业务模块。
  • 分析:可进一步服务化,如将公用配置表、字典表或相关业务表拆到单独的库中。

4. 垂直分表
  • 概念:以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。
  • 结果

    每个表的结构都不一样;

    每个表的数据也不一样,一般至少有一列交集(主键),用于关联数据;

    所有表的并集是全量数据。

  • 场景:系统绝对并发量未上来,表的记录不多但字段多,热点数据和非热点数据在一起,导致数据库缓存数据行减少,查询时产生大量随机读IO。
  • 分析:将热点数据放在主表,非热点数据放在扩展表,减少随机读IO。关联数据应在业务Service层处理,避免使用join。

二、分库分表工具

  • sharding-sphere:jar包,前身是sharding-jdbc。
  • TDDL:jar包,Taobao Distribute Data Layer。
  • Mycat:中间件。

三、分库分表步骤

  1. 评估:根据容量(当前容量和增长量)评估分库或分表个数。
  2. 选key:选择均匀分布的key。
  3. 分表规则:确定分表规则(如hash或range等)。
  4. 执行:一般采用双写方式执行。
  5. 扩容问题:尽量减少数据的移动。

四、分库分表问题及解决方案

1. 非partition key的查询问题
  • 端上除了partition key只有一个非partition key作为条件查询

    映射法:通过映射表将非partition key映射到partition key。

    基因法:利用字段的某些位作为分库或分表的基因。

  • 端上除了partition key不止一个非partition key作为条件查询

    映射法:同上。

    冗余法:冗余数据,建立多个索引表。

  • 后台除了partition key还有各种非partition key组合条件查询

    NoSQL法:使用NoSQL数据库(如ES)进行复杂查询。

    冗余法:同上。

2. 非partition key跨库跨表分页查询问题
  • NoSQL法:使用NoSQL数据库(如ES)解决。
3. 扩容问题
  • 水平扩容库(升级从库法)

    扩容是成倍的,通过增加从库来扩展容量。

  • 水平扩容表(双写迁移法)

    同步双写:应用配置双写,部署。

    数据复制:将老库中的老数据复制到新库中。

    数据校验:以老库为准校对新库中的老数据。

    去掉双写:应用去掉双写,部署。

五、分库分表总结

  • 明确瓶颈:分库分表前需明确数据库瓶颈所在,合理选择分库还是分表,水平还是垂直。
  • 选key重要:选key既要考虑拆分均匀,也要考虑非partition key的查询。
  • 规则简单:拆分规则越简单越好,以满足需求为前提。

六、分库分表示例

示例GitHub地址:

https://github.com/littlecharacter4s/study-sharding