标签:语句 逻辑 分库 数据库 中间件 支持 MyCAT 分片 节点
一、原理
Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的 SQL 语句,首先对 SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
MyCat是目前最流行的分布式数据库中间插件,是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。
MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度 。
二、MyCAT 主要功能
1、读写分离
系统可配置是否开启读写分离,不开启读写分离机制,所有读写操作都发送到当前指定的数据库host连接上,也就是所有请求在同一个connection数据库连接里面。开启读写分离需要指定读写各自的host配置连接,所有读操作都自动发送到指定的 writeHost和readHost上
2、分库分表
分库分表的概念大家都知道,在原始的处理方式中底层查询分库分表的逻辑相对复杂相对来说分表操作查询次数与获取次数较多,此时MyCAT替我们解决了这个问题,它无需我们处理多个连接库,或多个表,只需要配置好逻辑库逻辑表就可以了,使用的时候和原始连接数据库相同,不需要关注过多的库和表。
3、基本概念
逻辑库——Schema
逻辑表——Table
分片节点——dataNode
节点主机——dataHost
分片规则——rule
全局序列号——sequence
3.1、逻辑库(Schema)
在实际的开发中,开发人员不需要知道数据库中间件的存在,开发人员只需要有数据库的概念就可以了。所以数据库中间件可以被看做是一个或者多个数据库集群构成的逻辑库。例如:上图中的例子,我们可以理解为系统先做了垂直切分,被分为了3个库,用户库,订单库,商品库,而这3个库就被称为逻辑库。
3.2、逻辑表(table)
既然有逻辑库,那么就有逻辑表,对于应用系统来说,读写数据的表,就是逻辑表。而逻辑表中的数据,则是被水平切分后,分布在不同的分片库中。如上图所示:假设用户库中有一张用户表,这个用户表就被称为逻辑表,而用户表又被水平切分为3个表,每一个表中都存储一部分用户数据。业务系统在进行用户数据的读写时,只需要操作逻辑表就可以了,后面的分片细节则由MyCat进行操作,这些对于业务开发人员来说是完全透明的。当然,有些表的数据量没有那么大,完全不需要进行分片,只在一个物理的数据库表中即可。
凡是我们做的数据水平切分的表,我们把它叫做分片表。而数据量比较小,没有进行分片的表,我们叫它非分片表。
在真实的业务系统中,往往存在着大量的字典表,这些表的数据基本上很少变动,比如:订单状态。我们查询的时候,往往需要关联字典表去查询,比如:查询订单时,需要把订单状态关联查出,如果订单表做了分片,分布在不同的数据库中,而订单状态表由于数据量小,没有做分片,那么我们查询的时候就要跨库关联查询订单状态,增加了不必要的麻烦,不如我们干脆把订单状态表冗余到所有的订单分片库中,这样关联查询就不需要跨库了。我们把这种通过数据冗余方式复制到所有的分片库中的表,叫做全局表。
3.3、分片节点(dataNode)
数据被切分后,一张大表被分到不同的分片数据库上面,每个分片表所在的数据库就叫做分片节点。
3.4、节点主机(dataHost)
数据切分后,每一个分片节点不一定都会占用一个真正的物理主机,会存在多个分片节点在同一个物理主机上的情况,这些分片节点所在的主机就叫做节点主机。为了避免单节点并发数的限制,尽量将读写压力高的分片节点放在不同的节点主机上。
3.5、分片规则(rule)
一个大表被拆分成多个分片表,就需要一定的规则,按照某种业务逻辑,将数据分到一个确定的分片当中,这个规则就叫做分片规则。数据切分选择合适的分片规则非常重要,这将影响到后的数据处理难度,结合业务,选择合适的分片规则,是对架构师的一个重大考验。对于架构师来说,选择分片规则是一个艰难的,难以抉择的过程。
3.6、全局序列号(sequence)
大家有没有想过,数据切分以后,数据库表的中的id怎么办?原来在一张表的时候,我们采用id自增,但是数据分布到多个库怎么办?比如:向用户表插入数据,第一条记录插入了用户库1,它的id为1;第二条记录插入了用户库2,如果是自增,它的id也为1。这样id就混乱了,我们也无法确定一条数据的唯一标识了。这时,我们需要借助外部的机制保证数据的唯一标识,这种保证数据唯一标识的机制,我们叫做全局序列号。
三、使用限制
1、网络协议
一般来说仅内网使用,没有实现加密通信协议,连通外网有安全问题
没有后端数据库之间的数据同步服务
目标是兼容MySQL7/8服务器,也一定程度兼容Mariadb,支持Mariadb客户端的批量插入特性
网络通信协议一定支持native_password验证,其他验证方式会自动切换到验证插件
支持超过16mb的报文
不支持压缩协议
不支持加密协议通信
2、事务特性
支持强一致性(不跨库)分布式事务
支持保存点(savepoint,v1.21-2021-11-10)
支持多语句
3、数值类型
mycat2对于单分片sql没有限制,而对于跨实例的sql使用有符号类型处理,可以尝试在mycat中把建表语句的字段类型改成decimal避开这个问题
4、DDL语句
不支持修改拆分键
支持物理库的视图视为普通表来使用
仅普通表支持外键
5、DML语句
DELETE语句
不支持涉及分布式运算的子查询。
不支持多表delete。
UPDATE语句
不支持涉及分布式运算的子查询。
不支持多表update。
SELECT语句
对于for update语句会把sql中出现的表都加锁。
具体是行锁还是表锁要看sql语句。
不支持SELECT INTO OUTFILE。
6、SET语句
支持SET SESSION级别的变量,但是不能被预处理语句引用变量,只有autocommit变量具有正确语义
不支持SET GLOBAL级别的变量
不支持SET USER级别的变量
7、SHOW语句
所有SHOW语句都视为兼容性SQL进行处理,发往prototype节点处理,所以不具备分布式语义
高级功能
不支持用户自定义数据类型(改代码), 自定义函数(改代码)
支持物理视图,但是不支持Mycat中的逻辑视图
不支持存储过程(改代码)
有限支持存储过程
不支持游标
不支持触发器
8、函数计算问题
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP());
在mycat2里面,函数计算是有先后的,结果与mysql有偏差
四、应用场景
理论上Mycat2与单机数据库差别不大,但是由于其涉及多个存储节点以及定位是事务型数据库,并不是所有应用场景都会特显优势,不适合需要拉取大量数据在Mycat运算的场景。以下是常见的用法。
目标场景
任意数据源合拼的分布式查询
管理多数据库实例
比如管理全国城市数据库
点查/范围查询分片数据
业务访问呈现点查/范围规律而且可以根据分片键分散访问压力
二阶段聚合汇总
比如统计求和,MySQL计算一部分和值,Mycat再对结果汇总
二阶段数据源汇总
比如利用子查询查询物理库数据,而Mycat再对结果汇总
单表访问读写分离
多租户场景
不适合场景
无分片条件的SQL
跨分片join多于3个表,不区分 分片表,单表,全局表
分片表不建议使用深分页即limit 10000,1;
标签:语句,
逻辑,
分库,
数据库,
中间件,
支持,
MyCAT,
分片,
节点
From: https://www.cnblogs.com/soft-engineer/p/16596176.html