本文章是对MyCat相关的介绍。但介绍的着重点不至于如何使用Mycat以及如何对Mycat进行配置。Mycat配置相关内容相信读者在网络上以及Mycat官方群里都能找到相应的解答。本文章的重点是介绍Mycat背后的逻辑实现。该文章是笔者从网络上学习汇总出来的结果,希望对各位读者有一定的帮助。如有不当内容,欢迎在评论留言。
- mycat是基于java语言编辑的数据库中间件,它遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理。
- mycat工作原理:拦截用户发送的SQL语句,对SQL语句做一些特定的分析:分片分析,路由分析,读写分离分析,缓存分析等。然后将sql发往后端真实的数据库。
-
三个配置文件
- schema.xml 定义逻辑库,表,分片节点等内容
- rule.xml 定义分片规则
- server.xml 定义用户以及系统变量相关变量。
-
数据切分方式:
- 垂直切分(分库):按照业务将不同业务场景的表切分到不同的数据库上。
- 水平切分:根据表中的数据逻辑关系,将同一个表中的数据按照某种添加拆分到不同的数据库上。
-
分库分表问题:
- 引入分布式事务
- 跨节点join问题
- 跨节点合并排序分页问题
- 多数据源问题
-
mycat join问题
- 表分组:子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组(Table Group)保证数据Join不会跨库操作.
-
mycat全局表:
- 全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性
- 全局表的查询操作,只从一个节点获取
- 全局表可以跟任何一个表进行 JOIN 操作
-
Share join
1. 目前支持2个表的join。原理是解析SQL语句,拆分成单表的SQL语句执行,然后把各个节点的数据汇集。
-
mycat 查询:MyCat的路由结果是通过分片字段和分片方法来确定的。
- 若查询条件中有分片字段,则直接路由给某个具体的分片
- 若查询条件中么有分片字段,此时MyCat无法计算路由,会将查询发送到所有节点执行,然后返回结果并聚合。
-
mycat 分页排序:
- 纯limit:MyCat将查询分发给各个DB节点去执行。但Mycat响应结果取决于哪个DB节点最先返回结果给MyCat。
- limit和排序:MyCat将查询分发给各个DB节点去执行。收到各个DB节点返回的结果后,对所有的结果进行最小堆运算。然后返回结果。
-
limit带偏移量和排序:
1. 对于有 limit m,n 的SQL语句,Mycat会对其进行改写,改写成 limit 0, m+n 来保证查询结果的逻辑正确性。 2. 然后将改写的SQL发给各个DB节点去执行。 3. 收到所有DB节点返回的结果后,对所有的结果进行最小堆运算。然后返回给前端用户 4. 缺点:及其耗费资源。对于K个DB节点,MyCat需要处理的数据量为(m+n)*t个。mycat不适合分页排序操作。
-
mycat事务实现。
- 应用开启事务后,MyCat标识该连接为非自动提交
- Mycat将后续的SQl通过非自动提交的连接去执行。
- 如果各个节点都执行成功,则MyCat给该连接标识为Prepare Ready状态。如果有一个节点执行失败,则标识为RollBack状态。
- MyCat等待引用后续发送的commit或rollBack命令。对于commit命令:若当前连接为Prepare Ready状态,则讲commit命令发送给各个DB节点上。
- 如果一个DB在commit时故障,其他DB节点执行commit成功,mycat会一直等待故障DB节点返回结果一直到TIMEOUT。导致事务一致性被破坏。故Mycat事务是弱一致性的。
-
分片规则
- 取模
- 分片枚举:通过配置文件中配置可能的枚举id,自己配置分片。
- 根据范围分片
- 按照日期分片
-
MyCat全局序列。
-
MyCat将sequence配置到文件中。对于每次的插入,MyCat都会更新一下classpath中的sequence_conf.properties文件中的sequence当前的值。
* 优点:本地加载,读取速度快。 * 缺点:抗风险能力差,MyCat所在的主动宕机后,无法读取本地文件。
-
数据库方式:利用数据库的一个表进行累加。MyCat会预加载一部分号段到MyCat的内存中。先从序列中取用号段,如果内存中的号段用完了MyCat再从数据库中取一次号段。
1. 如果MyCat崩溃了,则会浪费一个号段。Mycat重启会获取下一个号段。
-
时间戳方式:UUID=42位毫秒+5位机器ID+5业务编码+12重复累加
1. 优点:配置简单 2. 缺点:18位ID过长 3. 强依赖机器时钟,时钟回拨会造成序列化重复。
- 自主生产全局序列。
-
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。