mycat操作文档

在这里插入图片描述mycat入门使用

一. 数据库中间件

Mycat 是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。 由于前面讲的对数据进行分片处理之后,从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构 成了整个完整的数据库存储。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iovTUTHt-1581683528868)(tu/17.png)]

如上图所表示,数据被分到多个分片数据库后,应用如果需要读取数据,就要需要处理多个数据源的数据。 如果没有数据库中间件,那么应用将直接面对分片集群,数据源切换、事务处理、数据聚合都需要应用直接处理, 原本该是专注于业务的应用,将会花大量的工作来处理分片后的问题,最重要的是每个应用处理将是完全的重复造轮子。

Mycat作为一个中间件,应用程序直接访问它,不用再去管真实的数据库,而由Mycat来与真实的数据库进行交互,真实的数据库可能有多个

二.安装mycat

mycat 是使用 JAVA 语言进行编写开发,使用前需要先安装 JAVA 运行环境(JRE),由于 mycat 中使用了 JDK7 中的一些特性,所以要求必须在 JDK7 以上的版本上运行

MyCAT 有提供编译好的安装包,支持 windows、Linux、Mac、Solaris 等系统上安装与运行。

1.linux

linux 下可以下载 Mycat-server-xxxxx.linux.tar.gz 解压在某个目录下,注意目录不能有空格,在 Linux(Unix)下,建议放在 usr/local/Mycat 目录下,如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N8mpWGLW-1581683528869)(…\mycat操作文档\tu\1.png)]

目录解释如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vtTllFvl-1581683528870)(…\mycat操作文档\tu\2.png)]

bin 程序目录,存放了 window 版本和 linux 版本,除了提供封装成服务的版本之外,也提供了 nowrap 的 shell 脚本命令,方便大家选择和修改,进入到 bin 目录:

Linux 下运行:./mycat console,首先要 chmod +x *

注:mycat 支持的命令{ console | start | stop | restart | status | dump }

conf 目录下存放配置文件,server.xml 是 Mycat 服务器参数调整和用户授权的配置文件,schema.xml 是逻 辑库定义和表以及分片定义的配置文件,rule.xml 是分片规则的配置文件,分片规则的具体一些参数信息单独存 放为文件,也在这个目录下,配置文件修改,需要重启 Mycat 或者通过 9066 端口 reload.

lib 目录下主要存放 mycat 依赖的一些 jar 文件.

日志存放在 logs/mycat.log 中,每天一个文件,日志的配置是在 conf/log4j.xml 中,根据自己的需要,可 以调整输出级别为 debug,debug 级别下,会输出更多的信息,方便排查问题

注意:Linux 下部署安装 MySQL,默认不忽略表名大小写,需要手动到/etc/my.cnf 下配置 lower_case_table_names=1 使 Linux 环境下 MySQL 忽略表名大小写,否则使用 MyCAT 的时候会提示找不到 表的错误!

2.Windows

windows 下可以下载 Mycat-server-xxxxx-win.tar.gz 解压在某个目录下,建议解压到本地某个盘符根目录 下,如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Ugsm8rO-1581683528871)(…\mycat操作文档\tu\3.png)]

目录解释如下:

​ bin 程序目录,存放了 window 版本和 linux 版本,除了提供封装成服务的版本之外,也提供了 nowrap 的 shell 脚本命令,方便大家选择和修改,进入到 bin 目录:

​ Windows 下运行:运行: mycat.bat 在控制台启动程序,也可以装载成服务,若此程序运行有问题,也可以 运行 startup_nowrap.bat,确保 java 命令可以在命令执行。

​ Windows 下将 MyCAT 做成系统服务:MyCAT 提供 warp 方式的命令,可以将 MyCAT 安装成系统服务并 可启动和停止。

  1. 进入 bin 目录下, 输入 ./mycat start 启动 mycat 服务。

​ conf 目录下存放配置文件,server.xml 是 Mycat 服务器参数调整和用户授权的配置文件,schema.xml 是逻 辑库定义和表以及分片定义的配置文件,rule.xml 是分片规则的配置文件,分片规则的具体一些参数信息单独存 放为文件,也在这个目录下,配置文件修改,需要重启 Mycat 或者通过 9066 端口 reload。

​ lib 目录下主要存放 mycat 依赖的一些 jar 文件。

​ 日志存放在 logs/mycat.log 中,每天一个文件,日志的配置是在 conf/log4j.xml 中,根据自己的需要,可 以调整输出级别为 debug,debug 级别下,会输出更多的信息,方便排查问题。

三.启动mycat

本案例使用Windows

以管理员身份运行cmd,进入mycat的bin目录,这里有几个简单的操作命令

安装:

mycat install

启动:

mycat start

停止:

mycat stop

重启:

mycat restart

安装以后,我们就可以直接去服务里面启动与停止了,不用再使用命令[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8uEYxMxN-1581683528872)(…\mycat操作文档\tu\5.png)]

四.mycat入门案例(分库分表)

需求:我在云服务器与本机都安装有Myql,现在我要使用这两个Mysql共同来给我的应用程序提供服务,主要涉及到的是MAVEN_SSM数据下面的user表,下面分别给出sql:

本机Mysql执行的sql为:

drop database if exists MAVEN_SSM;
create database MAVEN_SSM;
use MAVEN_SSM;
create table user(
    id int not null auto_increment,
    username char(20) not null,
    password char(33) not null,
    address char(8) not null,
    birthday date,
    department_id int not null,
    primary key (id)
);
insert into user(id,username,password,address,birthday,department_id) values(1,'小余','123456','四川成都','2018-06-01',2);
insert into user(id,username,password,address,birthday,department_id) values(2,'小余','982352','成都大学','2015-04-03',3);

云服务器上执行的sql为:

drop database if exists MAVEN_SSM;
create database MAVEN_SSM;
use MAVEN_SSM;
create table user(
    id int not null auto_increment,
    username char(20) not null,
    password char(33) not null,
    address char(8) not null,
    birthday date,
    department_id int not null,
    primary key (id)
);
insert into user(id,username,password,address,birthday,department_id) values(3,'小王','982352','四川绵阳','1996-08-26',2);
Mycat的默认端口是:8066,对于应用程序来说,数据库名为Mycat的中间件逻辑数据库名,不再是某个真实的数据库名

Mycat的配置文件,在conf目录下面有:server.xml、schema.xml、rule.xml,以及ehcache.xml、log4j2.xml,我们主要使用前三个

首先配置:server.xml,将默认的该配置文件下的user全都删掉,新建了一个用户peng:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aa8srFzC-1581683528874)(…\mycat操作文档\tu\6.png)]

用户名:peng

其密码为:123456

其逻辑数据库名为:MYCAT_DB

是否为只读数据库:否

由于Mycat安装在本机,需要更换连接数据库的url为本机的Mycat中间件

    jdbc:mysql://localhost:3306/MAVEN_SSM1

改为

    jdbc:mysql://localhost:8806/MYCAT_DB1

其次配置schema.xml,配置数据库的表结构,配置分片

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="MYCAT_DB" checkSQLschema="false" sqlMaxLimit="100">
    <table name="user" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2" rule="mod-long"/>
</schema>

<dataNode name="dn1" dataHost="localhost" database="MAVEN_SSM"/>
<dataNode name="dn2" dataHost="remotehost" database="MAVEN_SSM"/>

<dataHost name="localhost" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostM1" url="localhost:3306" user="root" password="123456"></writeHost>
</dataHost>

<dataHost name="remotehost" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostM1" url="47.55.478.991:3306" user="root" password="123456"></writeHost>
</dataHost>
</mycat:schema>

这里的47.55.478.991:3306是云服务器mysql

最后配置rule.xml,我们在schema.xml中使用了mod-long规则,由于是两个节点来提供服务,这里我就将其设置为均分:比如插入时,一个一库,轮流进行[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0e5Vin9u-1581683528875)(…\mycat操作文档\tu\7.png)]

将count设置为2

更多的配置规则与详情,请查看Mycat的官方文档,官网可以找到

测试:为了方便这里使用的是Navicat

首先查看本机Mysql:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rsHGCzpu-1581683528875)(…\mycat操作文档\tu\8.png)]

查看云服务器Mysql:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jkL1tUlU-1581683528876)(…\mycat操作文档\tu\9.png)]

连接Mycat中间件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-buT7XWXm-1581683528877)(…\mycat操作文档\tu\10.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-alNZs6gZ-1581683528878)(…\mycat操作文档\tu\11.png)]

查询操作:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NKbN3eNq-1581683528879)(…\mycat操作文档\tu\12.png)]

插入操作1:

insert into user(id,username,password,address,birthday,department_id) values(4,'帅哥1','123456','四川成都','2018-06-01',2);

插入操作2:

insert into user(id,username,password,address,birthday,department_id) values(5,'帅哥2','123456','四川成都','2018-06-01',2);

这时候本机与云服务器的数据库,各插了一条,均匀分配。再次进入Mysql进行验证:

本机Mysql:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B1bGM70d-1581683528880)(…\mycat操作文档\tu\13.png)]

云服务器Mysql:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVTL3IRC-1581683528880)(…\mycat操作文档\tu\14.png)]

再次查询:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HY1MpzeQ-1581683528881)(…\mycat操作文档\tu\15.png)]

可以看到这里顺序是有问题的,我们需要使用order by

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2rAzRUL1-1581683528882)(…\mycat操作文档\tu\16.png)]

mycat详解

一.mycat的配置

1.schema.xml

Schema.xml 作为 MyCat 中重要的配置文件之一,管理着 MyCat 的逻辑库、表、分片规则、DataNode 以 及 DataSource。

2.server.xml

server.xml 几乎保存了所有 mycat 需要的系统配置信息。其在代码内直接的映射类为 SystemConfig 类。

3.rule.xml

rule.xml 里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法, 或者对表使用相同的算法但具体的参数不同。这个文件里面主要有 tableRule 和 function 这两个标签。在具体使用过程中可以按照需求添加 tableRule 和 function

二.mycat的join

Mycat 目前仅支持 跨库2 个表 Join,

性能建议

尽量避免使用 Left join 或 Right join,而用 Inner join

在使用 Left join 或 Right join 时,ON 会优先执行,where 条件在最后执行,所以在使用过程中,条件尽可能的在 ON 语句中判断,减少 where 的执行

少用子查询,而用 join。

三.全局序列号

在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。MyCat 提供了全局序列号,并且提供了包含本地配置和数据库配置等多种实现方式,这里介绍本地配置实现方式:

配置方式:

在 sequence_conf.properties 文件中做如下配置:

GLOBAL_SEQ.HISIDS=

GLOBAL_SEQ.MINID=1001

GLOBAL_SEQ.MAXID=1000000000

GLOBAL_SEQ.CURID=1000

其中 HISIDS 表示使用过的历史分段(一般无特殊需要可不配置),MINID 表示最小 ID 值,MAXID 表示最大 ID 值,CURID 表示当前 ID 值。

server.xml 中配置:

<system><property name="sequnceHandlerType">0</property></system>

注:sequnceHandlerType 需要配置为 0,表示使用本地文件方式。

使用示例:

insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);

缺点:当 MyCAT 重新发布后,配置文件中的 sequence 会恢复到初始值。

优点:本地加载,读取速度较快。

四.mycat分片

按照官方文档修改配置文件,如: 取模分片

此规则为对分片字段求摸运算。

<tableRule name="mod-long">
<rule>
<columns>user_id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>

配置说明: 上面 columns 标识将要分片的表字段,algorithm 分片函数, 此种配置非常明确即根据 id 进行十进制求模预算

官方文档中展示了十几种分片规则,这里不再一一举例

五.部署mycat

1.单节点 mycat 部署

单节点 mycat 的部署指的是只部署一台 mycat 服务器,如果这台 mycat 服 务器宕机了,mycat 就不可用了。

生产环境下建议部署mycat高可用集群

2.mycat 的高可用

下图是一个典型的 Mycat 系统高可用的方案:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qqnWOT3V-1581683528883)(tu/18.png)]

六.mycat的不足

1.insert into

不支持 Insert into 中不包括字段名的 SQL。

insert into x select from y 的 SQL,若 x 与 y 不是相同的拆分规则,则不被支持。

2.非分片字段查询

Mycat中的路由结果是通过分片字段分片方法来确定的。例如下图中的一个Mycat分库方案:

根据 tt_waybill 表的 id 字段来进行分片

分片方法为 id 值取 3 的模,根据模值确定在DB1,DB2,DB3中的某个分片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iWzYQKU6-1581683528884)(tu/19.png)]

如果查询条件中有 id 字段的情况还好,查询将会落到某个具体的分片。例如:

mysql>select * fromtt_waybill where **id** =12330;

此时Mycat会计算路由结果

12330 % 3 = 0 –> DB1

并将该请求路由到DB1上去执行。

如果查询条件中没有 分片字段 条件,例如:

mysql>select * fromtt_waybill where waybill_no =88661;

此时Mycat无法计算路由,便发送到所有节点上执行:

DB1 –> select * fromtt_waybill where waybill_no =88661; 
DB2 –> select * from tt_waybill where waybill_no =88661; 
DB3 –> select * from tt_waybill where waybill_no =88661;

3.分页排序

先看一下Mycat是如何处理分页操作的,假如有如下Mycat分库方案:

一张表有30份数据分布在3个分片DB上,具体数据分布如下

DB1:[0,1,2,3,4,10,11,12,13,14] 
DB2:[5,6,7,8,9,16,17,18,19] 
DB3:[20,21,22,23,24,25,26,27,28,29]

当应用执行如下分页查询时

mysql>select * fromtable limit 2;

Mycat将该SQL请求分发到各个DB节点去执行,并接收各个DB节点的返回结果

DB1: [0,1] 
DB2: [5,6] 
DB3: [20,21]

但Mycat向应用返回的结果集取决于哪个DB节点最先返回结果给Mycat。

如果Mycat最先收到DB1节点的结果集,那么Mycat返回给应用端的结果集为 [0,1],如果Mycat最先收到DB2节点的结果集,那么返回给应用端的结果集为 [5,6]

也就是说,相同情况下,同一个SQL,在Mycat上执行时可能会有不同的返回结果。

在Mycat中执行分页操作时必须加上排序条件才能保证结果的正确性,下面看一下Mycat对排序分页的处理逻辑。

mysql>select * fromtable orderby id limit 2;

各个DB节点的返回结果:

DB1: [0,1] 
DB2: [5,6] 
DB3: [20,21]

Mycat接收到各个DB节点的返回结果后,对其进行最小堆运算,计算出所有结果集中最小的两条记录 [0,1] 返回给应用。

但是,当排序分页中有 偏移量 (offset)时,处理逻辑又有不同。假如应用的查询SQL如下:

mysql>select * fromtable order by id limit 5,2;

各个DB节点返回的数据:

DB1:[10,11]
DB2:[16,17]
DB3:[20,21]

计算后返回给应用的结果集是 [10,11]

可是,对于应用而言,该表的所有数据明明是 0-29 这30个数据的集合,limit 5,2 操作返回的结果集应该是 [5,6],如果返回 [10,11] 则是错误的处理逻辑。

所以Mycat在处理 有偏移量的排序分页 时是另外一套逻辑——它会自动改写SQL再计算

最后mycat能返回正确的结果,但这个过程极其消耗内存和CPU资源。当偏移量更大时,资源消耗则是数十倍增加。

一句话概括:使用mycat分页排序极其消耗资源,效率不高

4.跨库任意表JOIN

先看一下在单库中JOIN的场景。假设在某库中有 playerteam 两张表,player 表中的 team_id 字段与 team 表中的id 字段相关联。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bflHdYx7-1581683528885)(tu/20.png)]

JOIN操作的SQL如下

mysql>selectp_name,t_name from player p, team t where p.no = 3 and p.team_id = t.id;

此时能查询出结果

如果将这两个表的数据分库后,相关联的数据可能分布在不同的DB节点上,如下图:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jftzFTHb-1581683528886)(tu/22.png)]

这个SQL在各个单独的分片DB中都查不出结果,也就是说Mycat不能查询出正确的结果集。

mycat官方给出了四种解决方法,但跨库join目前还没有完美的解决方案。

share join是mycat提供的一种跨库join方式

目前支持 2 个表的 join,原理就是解析 SQL 语句,拆分成单表的 SQL 语句执行,然后把各个节点的数据汇集。

具体操作需要修改配置文件,以下是普通join和share join的区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XrC7oNLy-1581683528887)(tu/23.png)]

lHdYx7-1581683528885)]

JOIN操作的SQL如下

mysql>selectp_name,t_name from player p, team t where p.no = 3 and p.team_id = t.id;

此时能查询出结果

如果将这两个表的数据分库后,相关联的数据可能分布在不同的DB节点上,如下图:[外链图片转存中…(img-jftzFTHb-1581683528886)]

这个SQL在各个单独的分片DB中都查不出结果,也就是说Mycat不能查询出正确的结果集。

mycat官方给出了四种解决方法,但跨库join目前还没有完美的解决方案。

share join是mycat提供的一种跨库join方式

目前支持 2 个表的 join,原理就是解析 SQL 语句,拆分成单表的 SQL 语句执行,然后把各个节点的数据汇集。

具体操作需要修改配置文件,以下是普通join和share join的区别

[外链图片转存中…(img-XrC7oNLy-1581683528887)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-92VFIncn-1581683528888)(tu/24.png)]

更多技术文章请关注公众号:架构师Plus,
扫码添加
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值