mysql分库分表

57 阅读3分钟

分库分表背景

单表数据行数超过1000w 或 库物理文件超 100G

数据膨胀到一定体积,对db和业务的稳定性造成影响:

  • 分表(水平):减少单表的数据量;
  • 分库(垂直):按照业务维度垂直拆分。解决多个表间IO竞争、单机容量等问题。
  • 按时间冷热数据(库表)

分库分表策略

分库分表是一种水平拆分,根据如ID、用户、时间等维度进行数据拆分,拆分算法可以是取模、哈希、区间或者使用数据路由表等。

range:

假设以range方式分表,为保证数据均匀,一般以有序列的字段来分表,比如id或时间。实际上时间也可能造成单表数量的不均匀。所以id最佳,例如:每一百万个id分一张表

  • 优点:可以通过id明确的定位到一张表,根据id做范围查询、排序比较方便
  • 缺点:使用其他条件查询无法定位到具体的表和记录

hash:

确定增长量,确定要分多少张表

  • 优点:可以通过id明确的定位到一张表,数据分散,单表压力降低。
  • 缺点:不具备排序功能,后台查询不方便。扩展不方便。使用其他条件查询无法定位到具体的表和记录

实施

  • 使用应用层依赖中间件 或者 中间层代理类中间件。
    • 中间件层:

优点:

      • 对应用透明,应用就像查单表一样查询中间件层;
      • 支持多种编程语言,不受限于特定的语言;
      • 可以减少应用的总数据库连接数,避免因为应用过多导致数据库连接不够用

缺点:

      • 维护中间件
      • 考虑中间件的HA/负载均衡等,增加了部署和维护的困难。

现有:

    • 应用层

优点:就是无需额外部署,只要和应用绑定一起发布即可

缺点:就是不能跨语言,比如Java写的sharding-jdbc显然不能用在C#项目中,所以携程的dal也要重新写一套C#的客户端。

  • 分库分表后,join、排序分页、事务是否支持。

分库分表要考虑

问题方案
跨库跨表join和排序分页、范围查询、分组查询1.对所有表进行扫描然后做聚合;2.生成全局表、进行查询维度的数据异构(比如:订单库按照查询维度异构出商家订单库、用户订单库);3.将数据同步到ES搜索(binlog - kafka - es)
分布式唯一主键(自增ID)1.sequence id,auto_increment就是这种类型的,通常与数据库绑定,redis incr也是属于这种策略。2.- 全局唯一算法id,比如uuid、guid等,与机器、时间相关,通过算法保证不会有重复的id生成。3.- 分布式ID生成器,比如snowflake,返回值是一个数字,根据这个数字可以排序,也可以生成自己的业务流水号。
分布式事务(尽量设计为最终一致性)1.事务表;2.补偿机制(执行、会滚);3.TCC模式;4.Sagas模式;……
  • 性能问题:单表变多表,聚合查询、多维度查询性能会大大降低
  • 扩展性可能会降低,维护成本变高

分库分表中间件介绍

分库分表:中间件最全方案对比

MySQL Fabric原理(主要是HA和分片这2个功能)_赛里的技术博客_51CTO博客

分库分表神器 Sharding-JDBC,几千万的数据你不搞一下?

Sharding-JDBC 分库分表,真香!

kingshard

转:

亿级架构网站核心技术

对比7种分布式事务方案,还是偏爱阿里开源的Seata,真香!(原理+实战)