前言:
Mycat读写分离和自动切换机制,需要mysql的主从复制机制配合,即读从从机(slave)中读取,写向主机(master)中写入!
所以我们需要先完成mysql的主从备份
一 mysql主从备份
因为我之前以及写过一篇文章了,大家可以看完写的博客,或者,在网上找一些其它配置资料
点击跳转
二 安装mycat
第一步:mycat需要jdk环境,请安装jdk
第一步: 我这里在master中安装mycat,即直接下载mycat安装包,解压即可
mycat-1.6下载
tar -zxvf mycat-1.6
其一级目录如下
- mycat
- bin
mycay的执行文件目录 - catlet
- conf
mycat的配置文件其中(server.xml,rule.xml以及schema.xml最为重要) - lib
mycat自身需要的依赖 - logs
mycat的日子文件。发生错误,可以到这里查看 - version.txt
mycat的版本信息
- bin
三 conf配置文件
使用mycat只需要配置相关文件即可,其中以server.xml,rule.xml以及schema.xml最为重要、
- server.xml
配置使用逻辑库和逻辑表的用户情况 - rule.xml
配置分库分表的规则 - schema.xml
配置逻辑库与逻辑表,以及实际库和实际表
这里说到了逻辑库和逻辑表是说,mycat对外提供一个数据库和一个表,你可以向操作MySQL一样操作它,不用关心其中真实的数据在那个分库那个分表。如下
3.1 在schema.xml中配置逻辑库与逻辑表
schema.xml中
- 定义逻辑库
定义逻辑库,名字为TESTDB,不检查输入的sql语句的规范,每条sql语句默认加上limit 100,如果你加入limit则该sqlMaxLimit失效
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
- 定义逻辑表
#定义逻辑库中的逻辑表travelrecord,其真实数据在dn1,dn2,dn3的MySQL中(后面定义的),其mycat的数据分布规则为auto-sharding-long(默认)改为crc32slot这样会根据算法将写入的数据也会分布到不同的数据库中,这个规则需要在rule.xml中配置
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="crc32slot" />
#定义dataNode,即真实的MySQL数据的地址name为代表,其真实地址为localhost1(后面有定义),数据库为db1
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
#定义dataHost,即真实的MySQL数据的IP主机地址dbType(数据库类型mysql),dbDriver驱动(mysql,因为mycat本身就是为MySQL做的,所以你写native就是MySQL,其它数据库则需要你写完整的dbDriver),balance为平衡策略,一般用3(balance="3":表示写请求只发给节点,读请求只发给读节点这里要改,否则后面读写无效)
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 写入数据向那个真实的数据库写入,一般是MySQL的主-->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="123456">
<!--读数据向那个真实的数据库读,一般是MySQL的从-->
<readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" />
</writeHost>
</dataHost>
使用crc32slot只会将数据分配到两个数据库中,再配置文件rule.xml中有,但是我们分配到了3个数据库(db1,db2,db3后面会配置),所以我们需要修改配置,改为3
如果你这里忘记配置,并且以及开始mycat,那么你再修改为3时,必须将conf/ruledata目录(这个目录会在你使用mycat插入数据的时候生成)删除,再重新启动mycat,否则没有效果,因为分片规则以及生成,只有将其删除运行再生成!
下面这张图就是我后面使用mycat插入数据后,ruledata/crc32slot_MYCATTEST.properties 的内容
一共分三片,如果你没有该为3,这里就只有0 和1
- 0 = 0- 34132
表示_slot为0-34132的在数据库0中 - 1 = 34133 - 68266
表示_slot为34133 - 68266的在数据库1中 - 2 = 68266 - 102399
表示_slot为 68266 - 102399的在数据库2中
其中_slot为你创建表以后,mycat会自动在每张表加一个_slot字段
根据自身的MySQL的主从的信息配置如下(删掉了注释以及不需要的部分)
1 <?xml version="1.0"?>
2 <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
3 <mycat:schema xmlns:mycat="http://io.mycat/">
4
5 <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
6 <!-- auto sharding by id (long) -->
7 <table name="mycattest" dataNode="dn1,dn2,dn3" rule="crc32slot" />
9 </schema>
10
11 <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
12 /> -->
13 <dataNode name="dn1" dataHost="localhost1" database="db1" />
14 <dataNode name="dn2" dataHost="localhost1" database="db2" />
15 <dataNode name="dn3" dataHost="localhost1" database="db3" />
16
17 <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
18 writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
19 <heartbeat>select user()</heartbeat>
20 <!-- can have multi write hosts -->
21 <writeHost host="hostM1" url="192.168.25.5:3306" user="root"
22 password="123456">
23 <!-- can have multi read hosts -->
24 <readHost host="hostS2" url="192.168.25.6:3306" user="root" password="123456" />
25 </writeHost>
26 </dataHost>
27 </mycat:schema>```
3.2 在server.xml中配置用户登陆mycat的信息
主要查看server.xml中的用户配置信息
# 登陆mycat的用户配置
<user name="root">
用户是root,密码是123456,该用户只能操作TESTDB逻辑库
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
这里你可以设置该用户对逻辑库TESTDB的DML的权限设置
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
# 用户名为user密码为user,可以操作的逻辑库是TESTDB,但是是只读的
<user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
四 测试
4.1 根据之前的配置,我们需要修改MySQL主从中的用户登陆权限,让mycat可以登陆进去
- mysql_master 192.168.25.5
grant all privileges on . to root@’%’ identified by “123456”; #on 后面是* 点 *
再刷新权限
FLUSH PRIVILEGES;
- mysql_slave 192.168.25.6
grant all privileges on . to root@’%’ identified by “123456”; #on 后面是* 点 *
再刷新权限
FLUSH PRIVILEGES;
结果同上
4.2 测试读写分离
- 进入mycat安装目录的bin,启动
cd /root/mycat/bin
- 登陆mycat
mysql -h192.168.25.5 -uroot -p123456 -P8066
-u为你在mycat中的server.xml中配置的用户名,-p(小写)为该用户密码,-h为mycat的安装主机
-P (大写) 为mycat的端口
9066为管理端口管理端口用于执行管理命令:
8066命令端口用户执行增删改查等 SQL 语句:
如果出现 Unsupported statement 说明你使用的是9066端口操作(改为8066登陆),或者登陆的用户在mycat中的server.xml中权限受到了限制
- 查看逻辑数据库
- 查看逻辑表
- 为mysql_master配置数据库
因为在前面的schena.xml中配置了真实数据库的名字,但是我们还有没有创建,所以需要先创建出来,直接在master中写sql,语句即可,因为以及配置了主从,slave也会执行
create database db1;
create database db2;
create database db3;
- 测试
为已存在的逻辑表跟新你需要的完整信息
mysql> use TESTDB;
mysql> CREATE TABLE `mycattest` (
`id` int(255) NOT NULL,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
mysql>desc mycattest
这里我需要说明一下,为什么这里创建表结构,因为,表必须现在mycat中声明配置其相关属性(但是没有结构),后面mycat会自动为你生成一个逻辑表(mycattest),并会在你配置的主从数据库(db1,db2,db3)中加入该表(mycattest),此时该表是没有数据结构的,但是其分片分库的规则都以完成,所以你只需要完善其你需要的表结构即可!逻辑表必须先在schema.xml中声明配置规则
- 查看MySQL的主从数据结构
随意选择一个数据库(db1,db2,db3),注意mycat会自动增加一个字段_slot,根据该字段,mycat会把数据分散到你定义的片中(db1,db2,db3)
- 测试写
使用mycat写入5条数据
INSERT INTO mycattest(id,username,password) VALUES('2','gxm','123456');
INSERT INTO mycattest(id,username,password) VALUES('3','gxm','123456');
INSERT INTO mycattest(id,username,password) VALUES('4','gxm','123456');
INSERT INTO mycattest(id,username,password) VALUES('5','gxm','123456');
INSERT INTO mycattest(id,username,password) VALUES('6','gxm','123456');
查看master与slave是否都已插入数据,如果主从都已有数据,说明写是分离的,因为只有mycat向master中写入数据,slave才会只有相同的一份数据,因为如果同时向master与slave写入
- 第一种报错主键重复(如果不是,我这里就应该报错,id为主键)
- 第二种,数据会重复,master与slave每个都会会有10条数据(如果没有主键的话)
但是现在这里上述2中情况没有出现说明,是单独向master写入,由slave同步master的结果
因为我们配置是rule是crc32slot配置了分片所以数据会根据_slot大致均匀的分到到db1,db2,db3中
- 测试读
我向slave中写入一条记录
INSERT INTO db1.mycattest(id,username,password) VALUES('999','slave','99999');
master不会同步slave,所以slave的数据会比master多一条’999’,‘slave’,‘99999’
此时我再使用mycat查询数据如果没有999号数据说明从master中读取,有999号数据说明从slave中读取
或者你可以使用9066端口登陆,查看sql语句的执行状况
show @@datasource;
关于使用9066或者8066端口的使用的一些常用命令,查看mycat状态等等,这片博客感觉写的挺好的!
点击跳转
五 mycat 表定义
而对于其它不用分库的表来说,我们可以设置mycat的全局表,这样我们只需要链接 mycat 这一个数据库,就可以操作所有的表了。
// 使用 type=”gloab” 则表示所有的分库节点都有它完整的数据,不区分
<table name=”sys_channel” primaryKey=”id” type=”gloab” dataNode=”dn1,dn2,dn3”/>
// 不使用则所分使用你定义的分片规则来实现rule="crc32slot"
<table name="sys_msg_communication" dataNode="dn1,dn2,dn3" rule="crc32slot" />
mycat 还有一些其它的表格式的定义,可以参考
https://blog.csdn.net/tototuzuoquan/article/details/80362892