前言
MyCAT 是一个开源的分布式系统,是一个数据库中间件。可以用 MyCAT 来实现读写分离、主从切换以及分库
分表等等强大的功能,但是有一点要清楚,MyCAT 只是作为中间件的角色,来 '拦截' 用户发送的 SQL ,经过
特定的分析(如分片分析,读写分析)之后,再将分析后的 SQL 发送给真正的物理数据库,最终再把结果返回
给用户
在这之前,先得配置物理数据库集群间的主从关系,并实现主从同步,这些操作都是在物理数据库中。可以参考
另一篇博客:CentOS7中使用Docker部署MySQL实现主从同步
本博客使用 MyCAT 来实现读写分离功能
工欲善其事必先利其器,操作 Linux 服务器得有一个用着舒服的客户端,这里推荐使用 MobaXterm
MobaXterm 下载地址:https://mobaxterm.mobatek.net/download.html
安装 MyCAT
1. 输入命令 cd /usr/local/ -> 进入目录
2. 输入命令 mkdir mycat -> 新建文件夹
3. 输入命令 cd mycat -> 进入目录
4. 输入命令 wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
-> 在线下载 MyCAT 压缩包
5. 输入命令 tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -> 解压缩
6. 输入命令 cd mycat -> 进入解压缩目录
+ bin MyCAT 启用停止目录
+ catlet MyCAT 扩展功能目录
+ conf MyCAT 配置文件目录
+ lib MyCAT 引入的 jar 目录
+ logs MyCAT 日志文件目录
version.txt MyCAT 版本信息文件
配置 MyCAT 用户及权限
1. 输入命令 cd conf -> 进入 MyCAT 配置文件目录
2. 输入命令 vim server.xml -> 编辑 server.xml 配置文件,此文件就是用来配置 MyCAT 用户及权限
3. 核心关注的地方有
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
... 省略部分配置内容 ...
<user name="root">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<!-- 表级 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 name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
- user 标签:配置用户及权限
- user 标签 -> name 属性:登录连接 MyCAT 的用户名
- user 标签 -> property 子标签 -> name="password":登录连接 MyCAT 的密码
- user 标签-> property 子标签 -> name="schemas":MyCAT 的逻辑数据库名称
- user 标签 -> privileges 子标签:配置用户针对表的增删改查权限,默认为所有表的读写权限都有
4. 这里只需要一个用户,所以注释掉第二个 user 标签,并配置第一个 user 标签,如
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
... 省略部分配置内容 ...
<user name="myCatUser">
<property name="password">myCatPwd</property>
<property name="schemas">myCatSchemas</property>
<!-- 表级 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 name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
-->
</mycat:server>
5. 轮流输入命令 esc -> shift + 冒号 -> wq -> 回车
配置 MyCAT 读写分离
1. 输入命令 vim schema.xml -> 编辑 vim schema.xml 配置文件,此文件就是用来配置 MyCAT 读写分离
2. 可以看到 schema.xml 里有一些模板配置了,实际上只实现读写分离配置是很简单的,所以这里重写一个
3. 轮流输入命令 esc -> shift + 冒号 -> q -> 回车
4. 输入命令 cp schema.xml schema.xml.bak -> 备份
5. 输入命令 vim schema.xml -> 编辑 vim schema.xml 配置文件
6. 把里面的内容全部删除
7. 配置读写分离,如
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="myCatSchemas" checkSQLschema="false" sqlMaxLimit="100" dataNode="myCatDataNode"></schema>
<dataNode name="myCatDataNode" dataHost="myCatDataHost" database="masterSlaveDB" />
<dataHost name="myCatDataHost" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="mysql-master" url="127.0.0.1:3306" user="root" password="123456">
<readHost host="mysql-slave1" url="127.0.0.1:3307" user="root" password="123456"></readHost>
<readHost host="mysql-slave2" url="127.0.0.1:3308" user="root" password="123456"></readHost>
</writeHost>
</dataHost>
</mycat:schema>
- 由于是层层相关联,所以从最里层说起比较合适
- ------------------------------------------------------------------------------------------------------------------------------------
- readHost 标签:指定读实例
- readHost 标签 -> host 属性:标识不同的实例
- readHost 标签 -> url 属性:指定连接实例的 url 地址
- readHost 标签 -> user 属性:指定连接实例的用户名
- readHost 标签 -> password 属性:指定连接实例的密码
- ------------------------------------------------------------------------------------------------------------------------------------
- writeHost 标签:指定写实例
- writeHost 标签 -> host 属性:标识不同的实例
- writeHost 标签 -> url 属性:指定连接实例的 url 地址
- writeHost 标签 -> user 属性:指定连接实例的用户名
- writeHost 标签 -> password 属性:指定连接实例的密码
- ------------------------------------------------------------------------------------------------------------------------------------
- heartbeat 标签:心跳检查,select user() 通常用于 MySQL 数据库的心跳检查
- ------------------------------------------------------------------------------------------------------------------------------------
- dataHost 标签:定义数据库的实例,配置读写分离等
- dataHost 标签 -> name 属性:唯一标识,供上层调用
- dataHost 标签 -> maxCon 属性:连接池最大连接数量
- dataHost 标签 -> minCon 属性:初始化连接池连接数量
- dataHost 标签 -> balance 属性:负载均衡,配置 1 指所有读操作会随机发送到 readHost 实例上
- dataHost 标签 -> writeType 属性:负载均衡,配置 0 指所有写操作会发送到可用的 writeHost 实例上
- dataHost 标签 -> dbType 属性:指定物理数据库类型
- dataHost 标签 -> dbDriver 属性:指定物理数据库使用的 Driver
- dataHost 标签 -> slaveThreshold 属性:延迟时间,确保读到的数据是相对较新
- ------------------------------------------------------------------------------------------------------------------------------------
- dataNode 标签:数据节点,也是通常所说的数据分片
- dataNode 标签 -> name 属性:数据节点名称,具有唯一性,供上层调用
- dataNode 标签 -> dataHost 属性:指定该数据节点的数据库实例(dataHost 标签 -> name 属性)
- dataNode 标签 -> database 属性:物理数据库名称
- ------------------------------------------------------------------------------------------------------------------------------------
- schema 标签:配置逻辑数据库
- schema 标签 -> name 属性:与上面配置的 server.xml 中配置的逻辑数据库名称一致
- schema 标签 -> checkSQLschema 属性:是否去掉 SQL 中 db.table 的 db. 前缀,这里设置默认 false
- schema 标签 -> sqlMaxLimit 属性:如果 select 没有 limit,会默认添加 limit 关键字,避免查询全表
- schema 标签 -> dataNode 属性:指定该逻辑数据库的数据节点(dataNode 标签 -> name 属性)
8. 轮流输入命令 esc -> shift + 冒号 -> wq -> 回车
9. 按照上面配置好后有几点需要注意
① 以上都是以 CentOS7中使用Docker部署MySQL实现主从同步 这篇博客中 MySQL 实例来配置的
② writeHost 配置的 MySQL 实例是主库,readHost 是两个从库
③ dataNode 标签 -> database 属性配置的物理数据库在 Docker 容器启动时就自动生成了
④ 需把三个 Docker 容器都启动成功
配置 MyCAT 日志输入级别
1. 输入命令 cd /usr/local/mycat/mycat/conf/ -> 进入 MyCAT 配置文件目录
2. 输入命令 vim log4j2.xml -> 编辑 log4j2.xml
3. 把 level="info" 更改为 level="debug"
<asyncRoot level="debug" includeLocation="true">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile"/>
</asyncRoot>
4. 轮流输入命令 esc -> shift + 冒号 -> wq -> 回车
启动 MyCAT
1. 输入命令 cd /usr/local/mycat/mycat/bin/ -> 进入 MyCAT 启动目录
2. 输入命令 ./mycat start -> 启动 MyCAT
3. 顺便记录一下其他常用命令
4. 输入命令 ./mycat stop -> 停止 MyCAT
5. 输入命令 ./mycat restart -> 重启 MyCAT
6. 输入命令 ./mycat status -> 查看 MyCAT 状态
连接 MyCAT
1. 输入命令 mysql -h127.0.0.1 -P8066 -umyCatUser -pmyCatPwd -> 连接 MyCAT
- -h:指定 host
- -P:指定端口,MyCAT 默认端口为 8066
- -u:用户名,在 server.xml 中配置的
- -p:密码,在 server.xml 中配置的
验证读写分离
1. 输入命令 show databases; -> 显示所有库
mysql> show databases;
+--------------+
| DATABASE |
+--------------+
| myCatSchemas |
+--------------+
1 row in set (0.00 sec)
mysql>
2. myCatSchemas 就是 server.xml 中配置的 MyCAT 的逻辑数据库名称
3. 输入命令 use myCatSchemas; -> 操作此库
4. 输入命令 show tables; -> 显示所有表
mysql> show tables;
+-------------------------+
| Tables_in_masterSlaveDB |
+-------------------------+
| masterSlaveTable |
+-------------------------+
1 row in set (0.01 sec)
mysql>
5. 这时候就要对表进行增删改查操作了,这些操作都会被记录到 logs/mycat.log 文件里面
6. 由于日志级别被更改为 debug ,所以这里再开一个虚拟机操作 tab 页,来捕捉最新的日志信息
7. 在新的 tab 页中输入命令 cd /usr/local/mycat/mycat/logs/ -> 进入到 MyCAT 日志目录
8. 输入命令 tail -f mycat.log -> 打印日志
9. 回到步骤 4 的 tab 页,进行一个删除操作,三个查询操作
10. 输入 SQL:delete from masterSlaveTable where id = 6; -> 根据主键 id 删除
11. 输入 SQL:select * from masterSlaveTable ; -> 查询指定表全部数据
12. 输入 SQL:select * from masterSlaveTable ; -> 查询指定表全部数据
13. 输入 SQL:select * from masterSlaveTable ; -> 查询指定表全部数据
14. 到输出日志的 tab 页中捕捉关键日志
... 省略部分日志 ...
con:MySQLConnection [id=7, lastTime=1563614659410, user=root, schema=masterSlaveDB, old shema=masterSlaveDB, borrowed=true, fromSlaveDB=false, threadId=31, charset=utf8, txIsolation=3, autocommit=true, attachment=myCatDataNode{delete from masterSlaveTable where id = 6}, respHandler=SingleNodeHandler [node=myCatDataNode{delete from masterSlaveTable where id = 6}, packetId=0], host=127.0.0.1, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
... 省略部分日志 ...
con:MySQLConnection [id=17, lastTime=1563614660875, user=root, schema=masterSlaveDB, old shema=masterSlaveDB, borrowed=true, fromSlaveDB=true, threadId=20, charset=utf8, txIsolation=3, autocommit=true, attachment=myCatDataNode{select * from masterSlaveTable}, respHandler=SingleNodeHandler [node=myCatDataNode{select * from masterSlaveTable}, packetId=0], host=127.0.0.1, port=3307, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
... 省略部分日志 ...
schema=masterSlaveDB, old shema=masterSlaveDB, borrowed=true, fromSlaveDB=true, threadId=21, charset=utf8, txIsolation=3, autocommit=true, attachment=myCatDataNode{select * from masterSlaveTable}, respHandler=SingleNodeHandler [node=myCatDataNode{select * from masterSlaveTable}, packetId=10], host=127.0.0.1, port=3307, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
... 省略部分日志 ...
schema=masterSlaveDB, old shema=masterSlaveDB, borrowed=true, fromSlaveDB=true, threadId=18, charset=utf8, txIsolation=3, autocommit=true, attachment=myCatDataNode{select * from masterSlaveTable}, respHandler=SingleNodeHandler [node=myCatDataNode{select * from masterSlaveTable}, packetId=10], host=127.0.0.1, port=3308, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
... 省略部分日志 ...
15. 第一条删除的语句在端口为 3306 的 MySQL 实例中执行的(在主库中)
16. 剩下三条查询的语句分别在端口为 3307 和 3308 的 MySQL 实例中执行的(在两个从库中)
17. 证明读写分离成功
18. 注意 3306、3307 和 3308 端口的开启
安全组
注:如果服务器是在阿里云租用的需要设置安全组
1. 登录到阿里云
2. 进入到 '云服务器 ECS' 控制台
3. 左侧栏中选择 '实例'
4. 进入实例详情,点击左侧栏中 '本实例安全组'
5. 点击安全组中的 '配置规则'
6. 点击 '添加安全组规则' 按钮
7. 配置 3306、3307 和 3308 端口
防火墙
注:如果服务器是在阿里云租用的需要开启防火墙。服务器是默认不开启防火墙的,感觉不安全
1. 输入命令 systemctl status firewalld -> 查看防火墙状态
2. 输入命令 systemctl start firewalld -> 开启防火墙
3. 如果你不想开防火墙的话,那就输入命令 systemctl stop firewalld -> 关闭防火墙
4. 输入命令 systemctl restart firewalld.service -> 重启防火墙
端口
注:端口操作需要在开启防火墙的情况下才能执行成功。如下三条命令只需要执行一组即可
1. 输入命令 firewall-cmd --permanent --zone=public --add-port=3306/tcp -> 永久开放 3306 端口
输入命令 firewall-cmd --permanent --zone=public --add-port=3307/tcp -> 永久开放 3307 端口
输入命令 firewall-cmd --permanent --zone=public --add-port=3308/tcp -> 永久开放 3308 端口
2. 输入命令 firewall-cmd --zone=public --add-port=3306/tcp -> 临时开放 3306 端口
输入命令 firewall-cmd --zone=public --add-port=3307/tcp -> 临时开放 3307 端口
输入命令 firewall-cmd --zone=public --add-port=3308/tcp -> 临时开放 3308 端口
扩展
希望能够帮助到你
over