Mycat简介
- 一个数据库中间件产品
- 一个彻底开源的,面向企业应用开发的大数据库集群
- 支持 事务、ACID、可以替代 MySQL的加强版数据库
- 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
- 一个融合内存缓存技术、NoSQL技术、HDFS大数据的 新型SQL Server结合传统数据库和 新型分布式数据仓库的新一代 企业级数据库产品
参考资料
Mycat 学习文档:http://www.mycat.org.cn/document/mycat-definitive-guide.pdf
mycat 网站:http://www.mycat.org.cn/
java jdk安装博文:https://www.cnblogs.com/wjup/p/11041274.html
mycat github仓库:https://github.com/MyCATApache/Mycat-download
mycat 基本逻辑结构(思维导图):https://kdocs.cn/l/shHheJJd9tG0

Mycat安装
Windows下安装mycat
1、安装 java jdk
安装 java jdk 需要 jdk version > 1.7
2、安装mycat
安装完成后,正常启动bin文件下:
启动startup_nowrap ,直接双击运行 startup_nowrap.bat
或者使用Navicat工具去连接(但是响应时间会很长,不建议使用),推荐使用cmd命令连接mycat
小帖士:本文演示下载的版本地址是:Mycat-server-1.6.7.3
Linux下安装mycat
1、安装 java jdk
1.1、去Oracle官网下载需要安装的jdk版本,我这里用的是 jdk-8u181-linux-x64.tar.gz
1.2、解压安装
1 2 3 4
| # 解压文件 [root@localhost home]# tar -zxvf jdk-8u20-linux-x64.tar.gz # 移动到 use/local/java 软件安装目录 [root@VM-0-15-centos home]# mv jdk1.8.0_20 /usr/local/java
|
1.3、接下来就该配置 环境变量 了,输入以下指令进行配置:
1
| [root@localhost home]# vi /etc/profile
|
1 2 3 4 5 6 7
| set java environment JAVA_HOME=/usr/local/java JRE_HOME=/usr/local/java/jre CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin export JAVA_HOME JRE_HOME CLASS_PATH PATH
|
小帖士:其中 JAVA_HOME, JRE_HOME 请根据自己的实际安装路径及 JDK 版本配置。
1.4、编辑完之后,保存并退出,然后输入以下指令,刷新环境配置使其生效
1
| [root@localhost home]# source /etc/profile
|
1.5、测试是否安装成功
1 2 3 4
| [root@VM-0-15-centos java]# java -version java version "1.8.0_20" Java(TM) SE Runtime Environment (build 1.8.0_20-b26) Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
|
2、安装mycat
2.1、下载 mycat 后进行解压
1
| [root@VM-0-15-centos home]# tar -zxvf Mycat-server-1.6.7.3-release-20190828135747-linux.tar.gz
|
2.2、移动到 /usr/local/ 目录下
1 2
| [root@VM-0-15-centos home]# mv mycat /usr/local/mycat [root@VM-0-15-centos home]# cd /usr/local/mycat/
|
2.3、启动mycat
1 2 3 4 5 6 7 8 9
| [root@VM-0-15-centos mycat]# cd bin/
[root@VM-0-15-centos bin]# ./mycat Usage: ./mycat { console | start | stop | restart | status | dump }
[root@VM-0-15-centos bin]# ./mycat console
[root@VM-0-15-centos bin]# ./mycat start
|
2.5、修改 mycat 的 java 服务
1 2 3 4
| vim /usr/local/mycat/conf/wrapper.conf
wrapper.java.command=/usr/local/java/bin/java
|
2.4、连接mycat
1
| [root@VM-0-15-centos ~]# mysql -uroot -p123456 -h127.0.0.1 -P8066 --default_auth=mysql_native_password
|
小帖士:
由于 Mysql8 的缺省加密方式已经改为 caching_sha2_password ,而MyCat对此尚不支持。为此,需加
上 --default_auth=mysql_native_pasowrd 选项
mycat的默认配置密码是 123456,故这里用 123456 登录 mycat
Mycat的使用
配置文件简介
server.xml
该文件几乎保存了所有mycat需要的系统配置信息,包括 mycat 用户管理、DML权限管理等,其在代码内直接的映射类为SystemConfig 类。
Mycat 1.6的用户权限管理是通过server.xml实现的。在server.xml中通过用户标签和防火墙标签进行配置管理的
(1)设置password属性,设置用户的密码
(2)修改 readOnly 为 true 或 false 来限制用户对数据库是否可读写的权限,true为只读,false为读写
(3)修改 schemas 内的文本来控制用户可放问的 schema,多个schema用,号隔开
(4)设置benchmark属性:benchmark 基准, 当前端的整体 connection 数达到基准值是, 对来自该账户的请求开始拒绝连接,0 或不设表示不限制。
(5)设置usingDecrypt属性:是否对密码加密默认 0 否 如需要开启配置 1,同时使用加密程序对密码加密,加密命令方法是执行mycat的jar程序:
1
| java -cp Mycat-server-1.6.1-dev.jar org.opencloudb.util.DecryptUtil 0:user:password
|
vim查看用户配置(局部配置)信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <user name="root" defaultAccount="true"> <property name="password">123456</property> <property name="schemas">TESTDB</property>
</user>
|
schema.xml
用来定义mycat实例中的逻辑库,mycat可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用schema标签来划分这些不同的逻辑库。
如果不配置schema标签,所有表的配置会属于同一个默认的逻辑库。
逻辑库的概念和MySql的database的概念一样,我们在查询两个不同逻辑库中的表的时候,需要切换到该逻辑库下进行查询。
(注意:进行查询的时候需要在server.xml配置相关用户权限信息)
vim查看数据源信息如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| <dataHost name="localhost1" 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"> <readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" /> </writeHost> <writeHost host="hostS1" url="localhost:3316" user="root" password="123456" /> </dataHost>
|
rule.xml
里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法, 或者对表使用相同的算法但具体的参数不同。这个文件里面主要有 tableRule 和 function 这两个标签。在具体使 用过程中可以按照需求添加 tableRule 和 function
Mycat的简单使用
接下来的实现需求如下
- 数据库实现读写分离
- 对于插入的订单数据按照算法,除模取余的方式插入的不同的表中
- 对于查询根据除模取余算法,联查不同的表
- 满足对于那些分库分表后进行查询的业务需求
- 做全局表,实现插入一条数据后,该数据同时插入到对应的n个库中
在schema.xml配置数据源信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100"> <table name="order" primaryKey="id" subTables="order$0-9" dataNode="dn1" rule="mod-long" /> </schema> <dataNode name="dn1" dataHost="localhost1" database="my_test_db" /> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="127.0.0.1:33061" user="slave" password="slave"> <readHost host="hostS2" url="127.0.0.1:33062" user="slave" password="slave" /> </writeHost> </dataHost> </mycat:schema>
|
映射数据表说明
name=“order” 配置为 order 表
subTables=“order$0-9” 代表创建的10个order表(下文会创建的)
dataNode=“dn1” 表示数据源节点,可用逗号配置多个
rule=“mod-long” 用 除模取余 的方法,插入数据的时候,根据此方法插入到不同的表中。还有其他的方法,可查看 conf/rule.xml
指定数据源说明
name=“dn1” 这里是上文中定义的切片规则时定义的数据节点名称
dataHost=“localhost1” 这里是上文中定义的数据源的 dataHost 的 name 信息
database=“my_test_db” 这里是真实的数据库地址
数据库连接信息说明
balance=“0”, 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
balance=“1”,全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
balance=“2”,所有读操作都随机的在writeHost、readhost上分发。
balance=“3”,所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力
Tips:请确保连接的账号有足够的权限
mysql> show databases; # 用此检测 slave 能不能查到mycat中配置的 databases
在rule.xml配置分表算法
1 2 3 4
| <function name="mod-long" class="io.mycat.route.function.PartitionByMod"> <property name="count">10</property> </function>
|
因为接下来用 10 张表进行测试,所以我把这里的默认3改成了10
测试配置文件是否有误
1 2 3 4
| [root@VM-0-15-centos home]# cd /usr/local/mycat/bin/
[root@VM-0-15-centos conf]# ./mycat console
|
如果输出结果是 successfly 则表示正确,否则请查看日志,分析错误原因
重启mycat服务
1 2 3 4 5 6 7
| [root@VM-0-15-centos bin]# ./mycat stop Stopping Mycat-server... Stopped Mycat-server. [root@VM-0-15-centos bin]# ./mycat start Starting Mycat-server... [root@VM-0-15-centos bin]# ./mycat status Mycat-server is running (19070).
|
创建测试表进行测试
在端口号为 33061 的数据库服务器创建 my_test_db 数据库,然后创建 order0~order9 10张表用于测试
1 2 3 4 5 6 7 8
| CREATE TABLE `order` ( `id` int(11) NOT NULL AUTO_INCREMENT, `buyer` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `level` tinyint(4) DEFAULT NULL, `status` tinyint(4) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
测试mycat
1 2
| # 连接(-D 指定数据库) [root@VM-0-15-centos ~]# mysql -uroot -p123456 -h127.0.0.1 -P8066 -DTESTDB
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| # 插入一些数据 mysql> INSERT INTO order(id,buyer,name,level,status) VALUE(1,1,1,1,1); mysql> INSERT INTO order(id,buyer,name,level,status) VALUE(5,9,9,9,9); mysql> INSERT INTO order(id,buyer,name,level,status) VALUE(8,8,8,8,8); # 测试查询 mysql> select * from order order by level desc; + | id | buyer | name | level | status | + | 5 | 9 | 9 | 9 | 9 | | 8 | 8 | 8 | 8 | 8 | | 1 | 1 | 1 | 1 | 1 | + 3 rows in set (0.22 sec) # 分析被查询的表信息 mysql> explain select * from order order by level desc; + | DATA_NODE | SQL | + | dn1 | SELECT * FROM order0 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order1 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order2 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order3 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order4 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order5 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order6 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order7 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order8 ORDER BY level DESC LIMIT 100 | | dn1 | SELECT * FROM order9 ORDER BY level DESC LIMIT 100 | + 10 rows in set (0.00 sec)
|
通过可视化工具,看到这些数据已经用 除模取余 的方法,已经插入到不同的表中。
实现全局表
基于上面已经对schema.xml的更改,再做如下更改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100"> <table name="student" primaryKey="id" type="global" dataNode="dn1,dn2,dn3" /> </schema> <dataNode name="dn1" dataHost="localhost1" database="my_test_db" /> <dataNode name="dn2" dataHost="localhost1" database="my_test_db_2" /> <dataNode name="dn3" dataHost="localhost1" database="my_test_db_3" /> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="127.0.0.1:33061" user="root" password="root"> <readHost host="hostS2" url="127.0.0.1:33062" user="root" password="root" /> </writeHost> </dataHost> </mycat:schema>
|
进行测试
需要现在三个数据库(my_test_db、my_test_db_2、my_test_db_3)创建同样结构的表
然后连接 mycat 服务
开始插入数据
1 2
| mysql> INSERT INTO student(id,name) VALUE(1,1); Query OK, 1 row affected (0.30 sec)
|
然后,通过数据库管理工具,可以看到三个数据库都已经新增了这条数据
但是通过mycat却只能查到一个,这就是用mycat做数据库中间件的好处
1 2 3 4 5 6 7
| mysql> select * from student; +----+------+ | id | name | +----+------+ | 1 | 1 | +----+------+ 1 row in set (0.06 sec)
|
问题
1、命令窗使用mycat第一次查询或者插入出现如下错误,然后紧接着第二次操作错误消失
错误描述: ERROR 2006 (HY000): MySQL server has gone away
解决方案: 出现此错误的原因是,mycat和mysql建立了一个连接后,长时间没有操作mysql,mysql会自动把这个连接 kill 掉。你可以通过配置mysql的 max_allowed_packed 进行解决