前言
内容来源
本文内容均来源于网络,涉及地址
为什么要分库分表(个人理解,希望能与大家共勉)
https://blog.csdn.net/a992795427/article/details/84949760
浅谈分库分表
https://blog.csdn.net/huangshanchun/article/details/78885765
分库分表之sharding-jdcb
http://www.cnblogs.com/mr-yang-localhost/p/8120543.html
关于分库分表
其实分库分表是牵扯到高并发的,因为分库分表无非来说就是为了支撑高并发、数据量大的问题。
什么是分库分表?
将单个库拆分成多个库, 将单个表拆分成多个表,拆分规则策略, 后续说明
为什么要分库分表?
白话
分表
前提:当单表数据量太大,会极大的影响sql的执行性能,这时sql会跑的很慢。根据实战经验来说,当单表到几百万的时候,性能就会有所下降
个人理解:白话来说就是把一个表的数据放到多个表中,查就查一个表,可以按照id来分表控制每个表的数据量,比如单表固定在200W以内。
分库
单库而言,最大的并发可能就2000左右,但是一个健壮的单库来说最好的并发保持在1000左右。单数据库增大或者并发增加的时候,可以将一个库的数据拆分到多个库中。
分库分表的前因
- 新需求时,如果需要更新表结构,提交执行DDL(数据定义语言)会锁表,如果此时表数据量过大就会导致执行时间过长
- 表数据过大,DML(数据库操作语言)性能下降,响应时间缓慢
- 单机性能极限,采用以一主多策略,读写分离, 写的请求落在主节点上,读的请求落在从库上,但是如果从库过多会导致主从延时比较长,写入的数据不能立刻查到,这个需要看具体业务场景,是否需要强制查询主库。
分库分表前后对比
| 分库分表前 | 分库分表后 |
并发情况 | Mysql单机,支撑不了高并发 | Mysql集群,并发加倍 |
磁盘情况 | 磁盘容量几乎撑满 | 拆分多个表,磁盘使用率降低 |
SQL性能 | 数据量加大,SQL越来越慢 | 单表数据量少,SQL效率提升明显 |
怎么分?
拆分规则
水平拆分
就是把一个表的数据分到多个库的多个表中,每个库的表结构一样,不过每个库存放的数据不同。水平拆分的意思就是将数据均匀放到更多表里,然后多个库来抗高并发,还有就是用多个库的存储容量来扩容
垂直拆分
就是把一个很多字段的表拆分给多个表,或者多个库上去。每个库表结构都不一样,每个库表都包含部分字段。一般来说,会将很少访问的字段放到一个表,数据库有缓存,访问频率高的字段越少,可以缓存更多的行,性能更好,这个一般在表层面操作。
如何拆分
其实大家可能都遇到到,比如说把一个订单大表拆开,订单表、订单支付表、订单商品表。
按数据量
一种是按照range来分,每个库一段连续的数据,比如按时间来,但比较少用,比如大量流量产生大量数据。
按字段
一种是按照某个字段hash均匀分散,这个较常用
一个分表字段(一般是业务的主键 比如订单Id),然后水平拆分(分表字段取模分表总数),那么怎么选择这个分表字段呢主要需要考以下几点:
1.是否便于查询,比如订单表,我们也可以按照订单Id,也可以按照用户Id来分。但是有时候,我们希望分库分表后能够满足两个Id查询,比如订单Id和userId,希望同一个userId的所有订单都落到同一张表中,这样就可以采用组合方的式生成分表字段订单Id(全局自增主键+userId后四位),这种组合方式生成订单Id做分表字段,即可用满足订单Id查询又可以满足用户Id查询。
2.数据分配是否相对均匀,不会出现数据的倾斜问题,如果选择分表字段不是很合适就会导致一些表的数据比较多,而一些表的数据比较少,应当避免这种现象。
其他(组合拆分)
分库分表后问题如何处理?
面临问题
- 跨节点分页、排序、函数问题
- 跨节点关联查询 join 问题
- 事务一致性问题
- 全局主键避重问题
- 数据迁移、扩容问题
事务处理
夸库的事务不可用,原本的一个事务都是在同一库的(事务是基于连接的),分库后原本事务可能需要分到了不同的库,这样夸库的事务就会不可用。
采用分库分表中间件 – 处理事务
查询处理
非分表字段来查询的需求,这种情况下直接查询的性能非常低,需要扫描全表,这种情况可以通过将数据导入到ElasticSearch(搜索引擎)来解决,通过搜索引擎来满足查询非分表字段,也可以建立一个route表这个表想到于二级索引(路由表主要存储非分表字段到分表字段映射关系)。
目前常用分库分表中间件
sharding-jdbc
当当开源,属于client层,SQL语法支持比较多,支持分库分表、读写分离、分布式id生成、柔性事务(最大努力送达型事务、TCC事务),一直在维护,社区也比较活跃
参考使用sharding-jdbc网址: https://www.jianshu.com/p/e6385f802821
Mycat
基于proxy层方案,属于目前非常火且不断更新的数据库中间件,支持功能也非常完善
区别和选择
sharding-jdbc这种client层优点是不用部署,运维成本低,不需要代理层的二次转发请求,性能很高,但是一旦升级,需要各个系统都重新升级版本在发布,各个系统都需要耦合sharding-jdbc的依赖。
mycat这种proxy层的方案缺点就是自己运维一套中间件,运维成本高,但是好处在于对于各个项目透明,如果升级都是在中间件那里搞定就可以了。
通常来说,小公司小项目建议使用sharding-jdbc,维护成本低,而大公司使用mycat这种proxy方案,大公司系统和项目多,有专人维护。