- 一、MyCat历史
- 二、MyCat简介
- 三、数据切分
- 2.1 垂直切分
- 2.2 水平切分
- 四、MyCat原理
- 五、分库分表原则
- 六、数据分片规则
- 6.1 全局表
- 6.2 E-R分片表
- 6.3 多对多关联
要说MyCat的历史可能需要从阿里的Cobar说起,Cobar是阿里开源的一个MySql分布式处理中间件,它可以在分布式的架构环境下像传统数据库一样提供海量数据的存储与访问服务。2013年Cobar在使用过程中发现了一些比较严重的问题,此时MyCat应运而生,它基于Cobar开发改良,一些Cobar的用户也参与了MyCat的开发,最终MyCat发展成为一个由众多实力派开发人员参与维护的社区型开源软件。
由于当前互联网已然是进入了大数据时代,海量的数据存储和访问已经成为了传统的关系型数据库的瓶颈,但是非关系数据库又只能是作为关系型数据库的补充而不能够进行取代,所以就需要关系型数据库能够支持自动扩展、切分等功能,但是目前无论是开源或者是商用的关系型数据库均不支持大规模自动扩展和水平切分,所以只能通过第三方来进行数据切分,而做常用的这个“第三方”就是MyCat。
二、MyCat简介前面对于MyCat的起源做了简单介绍,那究竟什么是MyCat?从定义上来看MyCat是一个实现了mysql协议的server是一个数据库中间件,进行数据处理与交互的中间服务,前端可以将其看作是一个数据库代理:下图中体现了mycat在系统架构中的应用(当然这个是极简化的,毕竟还阔以集群嘛),是不是和nginx做代理服务器的应用有点像?
mycat核心的功能就是分库分表,即将一个数据量比较大的表水平切分成多个小表并存放到不同的数据库中。应用程序只需要对接mycat,然后由mycat集中处理与多个mysql之间的对接细节。
三、数据切分所谓的数据切分就是通过某种特定的数据划分条件对存放在同一个数据库中的数据进行分割并存放到多个数据库上,从而分散单台数据库的负载压力。
2.1 垂直切分一般对于数据量较小的应用都是将各种业务模块的数据表都存放在同一个数据库中
但是如果数据量较大的话,应用中的所有表都存放在一个数据库中显然会有瓶颈,毕竟数据库的存储容量不会是无限制的。所以对于这种情况我们可以进行数据垂直切分:
根据不同的业务分类将表分布到不同的数据库上,这样就分散了单台数据库的负载。
| 优点 | 缺点 |
|---|---|
| 业务清晰,拆分规则明确 | 部分表无法在数据库级别进行关联,需要在程序中完成,增加了程序复杂度 |
| 系统易于整合与扩展 | 事务处理复杂 |
| 容易定位,便于数据维护 | 因为业务分类不同,可能存在单库性能瓶颈 |
水平切分可以简单理解为按照表的数据行进行切分,切分之后形成的表拥有同样的属性,只是将原来的表的数据进行了分散。
| 优点 | 缺点 |
|---|---|
| 不存在单库大数据,高并发的性能瓶颈 | 分片事务一致性难以得到解决 |
| 应用端改造较少 | 数据多次扩展难度高,维护难度较大 |
| 提高了系统的稳定性和负载能力 | 跨库join性能差 |
在系统结构中引入了mycat之后,mycat会对发送到数据库的sql语句起到一个拦截的作用,例如:
我们的members表使用分片字段address+分片函数字符串枚举方式被分为3个分片并分布在3台服务器上,
我们在应用中进行如下sql查询:
select * from members where address="北京";
该sql会被mycat进行特定分析(分片分析、路由分析、读写分离分析……),先查找sql涉及的表,如果该表有分片规则则获取sql中的分片字段的值(北京),同时匹配分片函数,得到sql对应的分片列表(分片1),然后在该分片中执行sql语句,最后将执行结果合并处理之后返回给应用。
五、分库分表原则虽然通过数据分库分表能够降低负载,但并不是任何情况下都适合进行分库分表:
1.能不切分就不切分
2.如果一定要切分则需要选择最合适的切分规则
3.切分之后跨库join最好使用数据冗余和表分组的形式来解决
4.多表join能避免尽量避免
注:子表数据与所关联的父表记录存放在同一个分片上,保证数据join不会跨库
六、数据分片规则避免跨库join是分片的一条重要依据
6.1 全局表当我们的项目中需要存储一些诸如配置数据之类的情况下,可能他的数据量并不大,但是我们会在很多的业务模块中使用到他,那这种表适合于全局表,不需要对其进行切分,直接在每个分片上在存储一份此表,当需要对此表进行insert的时候,我们也直接将insert命令分发到存储此表的各个分片上分别执行,在其他表需要与此表进行聚合时优先与同一分片上的全局表进行join,避免跨库操作带来的不必要的麻烦。
mycat的分片规则一般通过配置文件进行配置:
这种分片原则很好理解,E-R分片表直观地讲就是将存在主从依赖关系的业务表的数据存放在同一个分片上,例如:用户基本信息表和‘信息修改明细记录表’之间,信息修改明细记录表总是会依赖于用户基本信息表,我们可以根据信息ID(infoId)来进行分片存储,确保相同的infoId会被分配到同一个分片上进行存储,这样就可以避免跨库join。
针对于主表A+关联表+主表B的业务情况,在关联表中可能同时存在主表A和主表B的主键,mycat暂时无法对这种情况进行3个表之间的关联进行很好的支持,所以关联表到底放在哪个分片上决定于他更加倾向于主表A还是主表B,后期的发展方向是关联表之间进行数据双向复制。
一般此种分片形式我们可以分为主键分片和非主键分片两种形式,非主键分片即使用某业务字段进行分片,比如我们之前做的一个项目就是使用了生产日期来进行分片,对于非主键分片的table我们填写primaryKey属性,mycat实现了主键到分片的缓存机制,我们在后续的查询中,mycat会先确认缓存中是否存在主键到分片的映射关系,这样可以大大提高查询效率。



