分库分表背景
单表数据行数超过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,几千万的数据你不搞一下?
转: