mysql分库分表研究.
名词解释
- database: 库
- table: 表
- sharding: 分库分表
为什么要分库分表?
在分库分表这之前可以先进行数据库的读写分离,这样读压力基本上就不考虑了,只剩下写的压力.
写库是不能增加的,只能有一个,否则会有一致性的问题,更加复杂.
这时就需要用到分库分表了,单库太大就分库,单表太大就分表.
有哪几种方式,区别与适用场景是什么?
一般有垂直切分
与水平切分
垂直分库/分表
垂直分库指根据业务拆分数据库,如用户库,订单库,商品库等
垂直分表指基于列字段进行拆分,一般将不常用,数据较大,长度较长的字段拆分到扩展表里
水平分库/分表
没有单独的水平分库
水平分表指针对数据量大的单表,按某种规则(如RANGE,HASH等),水平切分到多张表里. 但这些表还是在一个库里,库级别的数据库操作仍然有io瓶颈,因此一般采用水平分库分表.
水平分库分表指将单张表的数据水平切分到多个数据库中
水平分库分表规则
- RANGE: 如0-10000一个表,10000-20000一个表
- HASH: 如对id取模分表
- 地理区域: 如华南一个表,华东一个表
- 时间: 将旧的数据切出去放到另一个表(旧数据的查询概率小)
分库分表后有什么问题?
数据同步
需要在性能影响与数据时效性间取得平衡,避免跨库查询
事务
分库分表后,事务也变成了分布式事务.
如果依赖数据库本身的分布式管理功能,将付出昂贵的性能代价.
如果由应用程序去编码控制,又会有很大的编码负担,增加很大的复杂性.
跨库join
分库分表后无法join不同库的表,也无法join分表粒度不同的表,原本一次查询能完成的业务,可能需要多次查询才能完成.
解决方法:
- 全局表: 基础数据所有库都拷贝一份
- 字段冗余: 这样有些字段就不用join了
- 代码里组装: 分别查询,在代码里组装,较复杂
结果合并(group by, order by)
目前市场上开源的产品有哪些,有什么优缺点?
名称 | 公司 | 是否基于代理 | 基于 |
---|---|---|---|
Mysql fabric | 官方 | 非代理 | 无 |
MySQL Proxy | 官方 | 代理 | 无 |
ProxySQL | - | 代理 | - |
Atlas | 360 | 代理 | Mysql Proxy |
DBProxy | 美团 | 代理 | Atlas |
sharding-jdbc | apache | - | jdbc |
Cobar | 阿里巴巴 | 代理 | - |
TDDL | 阿里巴巴 | 非代理 | jdbc |
TSharding | 蘑菇街 | - | mybatis |
Vitess | youtube | 代理 | - |
MaxScale | MariaDB | - | - |
Amoeba | - | 代理 | - |
mycat | - | - | - |
Hibernate Shards | - | - | hibernate |
常见问题
后台报表join的表有n个,分库后怎么查?
其实,这一般是设计不合理,或技术选型有误. 报表类系统一般借助离线分析/流式计算等手段实现,而不应该直接在业务库中大量join.