实现单点Mycat读写分离
实现单点Mycat读写分离
下载链接1:Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz
下载链接2:Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz
如有下载不了请及时在评论区留言
架构图
主机名 | ip | 内存 | 硬盘 |
---|---|---|---|
master | 192.168.48.10 | 2G | 100G |
slave | 192.168.48.11 | 2G | 100G |
mycat | 192.168.48.128 | >=2G | 100G |
client | 192.168.48.101 | 2G | 100G |
部署主从复制
安装mysql
操作节点:[master,slave]
这是我的二进制mysql安装脚本,适用于大部分的linux通用安装,如果你有自己的安排可以直接略过这个,自己安装mysql
1 | wget https://blog.qianyios.top/file/mysql_install.sh |
配置master
1.修改配置文件
1 | vim /etc/my.cnf |
sever-id
:必须是整个集群里面唯一的,不能重复
log-bin
:后续会在/data/logbin生成qylog.000001的二进制文件,你可以自定义路径和文件名不用加后缀
1 | mkdir -p /data/logbin;chown -R mysql:mysql /data/logbin |
2.查看二进制文件的位置
1 | mysql -uroot -p123456 |
3.创建传输账号
1 | create user repluser@'192.168.48.%' identified by '123456'; |
配置从节点
1.修改配置文件
1 | #其他安装mysql的方法,你只需要确保有如下选项就行了 |
sever-id
:必须是整个集群里面唯一的,不能重复
log-bin
:后续会在/data/logbin生成qylog.000001的二进制文件,你可以自定义路径和文件名不用加后缀
1 | mkdir -p /data/logbin /data/relaylog |
启动复制线程
操作节点:[slave]
1 | mysql -u root -p123456 |
确保有两个yes就行了
如果你想重置线程可以用以下命令
1 | stop slave; |
有一个重要的点,因为二进制日志是记录你的操作的嘛,我们在开启二进制日志之后,不是在主节点
创建了一个repluser用户吗,那这个操作肯定也被记录,然后这不是主从复制了吗,这里肯定,也会同步,也会运行,二进制日志本身就是一个sql文件,普通cat是看不了,你得用这个命令
1 | [root@master ~]# mysqlbinlog -uroot -p123456 /data/logbin/qylog.000001 -v |
所有既然主从复制了,那在从节点,应该也运行了这个二进制文件,就说明从节点也有这个账号
1 | select host,user from mysql.user; |
测试
接下来在主节点导入测试数据
全选复制粘贴退出mysql
运行
1 | cat > hellodb.sql <<"EOF" |
在主节点导入
1 | mysql -uroot -p123456 < hellodb.sql |
在从节点查看是否同步
1 | mysql -uroot -p123456 hellodb -e "use hellodb;select * from teachers;" |
至此主从复制成功同步
部署mycat
注意:这台机上不能用mysql等其他数据库
操作节点:[mycat]
安装jdk
1 | wget https://alist.qianyios.top/d/%E6%B8%B8%E5%AE%A2/%E8%B1%86%E5%8C%85haha/%E8%BF%90%E7%BB%B4/mysql/%E5%AE%89%E8%A3%85%E5%8C%85/jdk-8u202-linux-x64.rpm?sign=1F6ZiF7m6XPKTiV2PiNEH2xIInIVrb2uHIm3TvyFXG0=:0 |
1 | [root@mycat ~]# java -version |
下载安装mycat
1 | wget https://alist.qianyios.top/d/%E6%B8%B8%E5%AE%A2/%E8%B1%86%E5%8C%85haha/%E8%BF%90%E7%BB%B4/mysql/%E5%AE%89%E8%A3%85%E5%8C%85/Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz?sign=T83V18vz0xSMy6INAGV9eAzETOL7c0gxQuZA5YYWlhw=:0 |
mycat安装目录结构:
- bin mycat命令,启动、重启、停止等
- catlet catlet为Mycat的一个扩展功能
- conf Mycat 配置信息,重点关注
- lib Mycat引用的jar包,Mycat是java开发的
- logs 日志文件,包括Mycat启动的日志和运行的日志
- version.txt mycat版本说明
logs目录:
- wrapper.log mycat启动日志
- mycat.log mycat详细工作日志
Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:
- server.xml Mycat软件本身相关的配置文件,设置账号、参数等
- schema.xml Mycat对应的物理数据库和数据库表的配置,读写分离、高可用、分布式策略定制、节点控制
- rule.xml Mycat分片(分库分表)规则配置文件,记录分片规则列表、使用方法等
启动和连接
1 | echo 'PATH=/apps/mycat/bin:$PATH' > /etc/profile.d/mycat.sh |
Mycat 主要配置文件说明
server.xml
存放Mycat软件本身相关的配置文件,比如:连接Mycat的用户,密码,数据库名称等
server.xml文件中配置的参数解释说明:
参数 | 说明 |
---|---|
user | 用户配置节点 |
name | 客户端登录 MyCAT 的用户名,也就是客户端用来连接 Mycat 的用户名。 |
password | 客户端登录 MyCAT 的密码 |
schemas | 数据库名,这里会和 schema.xml 中的配置关联,多个用逗号分开,例如:db1,db2 |
privileges | 配置用户针对表的增删改查的权限 |
readOnly | mycat 逻辑库所具有的权限。true 为只读,false 为读写都有,默认为 false |
注意:
- server.xml文件里登录mycat的用户名和密码可以任意定义,这个账号和密码是为客户机登录mycat时使用的账号信息
- 逻辑库名(如上面的TESTDB,也就是登录mycat后显示的库名,切换这个库之后,显示的就是代理的真实mysql数据库的表)要在schema.xml里面也定义,否则会导致mycat服务启动失败!
- 这里只定义了一个标签,所以把多余的都注释了。如果定义多个标签,即设置多个连接mycat的用户名和密码,那么就需要在schema.xml文件中定义多个对应的库!
schema.xml
是最主要的配置项,此文件关联mysql读写分离策略,读写分离、分库分表策略、分片节点都是在此文件中配置的.MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的
schema.xml文件中配置的参数解释说明:
参数 | 说明 |
---|---|
schema | 数据库设置,此数据库为逻辑数据库,name 与 server.xml 中的 schema 对应 |
dataNode | 分片信息,也就是分库相关配置 |
dataHost | 物理数据库,真正存储数据的数据库 |
配置说明
name属性唯一标识dataHost标签,供上层的标签使用。
maxCon属性指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost、readHost标签都会使用这个属性的值来实例化出连接池的最大连接数
minCon属性指定每个读写实例连接池的最小连接,初始化连接池的大小
每个节点的属性逐一说明
schema:
属性 | 说明 |
---|---|
name | 逻辑数据库名,与 server.xml 中的 schema 对应 |
checkSQLschema | 数据库前缀相关设置,这里为 false |
sqlMaxLimit | SELECT 时默认的 LIMIT ,避免查询全表 |
table
属性 | 说明 |
---|---|
name | 表名,物理数据库中表名 |
dataNode | 表存储到哪些节点,多个节点用逗号分隔。节点为下文 dataNode 设置的 name |
primaryKey | 主键字段名,自动生成主键时需要设置 |
autoIncrement | 是否自增 |
rule | 分片规则名,具体规则下文 rule 详细介绍 |
dataNode
属性 | 说明 |
---|---|
name | 节点名,与 table 中的 dataNode 对应 |
datahost | 物理数据库名,与 datahost 中的 name 对应 |
database | 物理数据库中数据库名 |
dataHost
属性 | 说明 |
---|---|
name | 物理数据库名,与 dataNode 中的 dataHost 对应 |
balance | 均衡负载的方式 |
writeType | 写入方式 |
dbType | 数据库类型 |
heartbeat | 心跳检测语句,注意语句结尾的分号要加 |
schema.xml文件中有三点需要注意:balance=“1”,writeType=“0” ,switchType=“1”
schema.xml中的balance的取值决定了负载均衡对非事务内的读操作的处理。balance 属性负载均衡类型,目前的取值有 4 种:
balance="0"
:不开启读写分离机制,所有读操作都发送到当前可用的writeHost上,即读请求仅发送到writeHost上
balance="1"
:一般用此模式,读请求随机分发到当前writeHost对应的readHost和standby的writeHost上。即全部的readHost与stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1 ->S1 , M2->S2,并且 M1 与 M2 互为主备),正常情况下, M2,S1, S2 都参与 select 语句的负载均衡
balance="2"
:读请求随机分发到当前dataHost内所有的writeHost和readHost上。即所有读操作都随机的在writeHost、 readhost 上分发
balance="3"
:读请求随机分发到当前writeHost对应的readHost上。即所有读请求随机的分发到wiriterHost 对应的 readhost 执行, writerHost 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有,1.3 没有
writeHost和readHost 标签
这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。
唯一不同的是:writeHost指定写实例、readHost指定读实例,组合这些读写实例来满足系统的要求。
在一个dataHost内可以定义多个writeHost和readHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去
注意:Mycat主从分离只是在读的时候做了处理,写入数据的时候,只会写入到writehost,需要通过mycat的主从复制将数据复制到readhost
修改server.xml文件配置Mycat的连接信息
1 | vim /apps/mycat/conf/server.xml |
1 | <property name="processorBufferPoolType">0</property> |
这里填的是用户去连接的mysql,也就是说用户用mysql -uroot -p123465
连的是mycat1的这个虚拟的TESTDB数据库,但是他映射的是后端的数据库,这个在下一步会讲到
修改schema.xml
1 | #直接复制我的文件就行了,全选一键复制,看一下有什么信息要修改,修改后就可以复制了 |
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> </schema>
这一行的dn1对应下面的这一行
<dataNode name="dn1" dataHost="localhost1" database="hellodb" />
TESTDB
是前面上一步修改server.xml提到的要和前面一一对应的虚拟数据库
hellodb
是后端对应的数据库名,就是说,我后端有哪个数据库是想映射到mycat的,就写,我总不能说所有数据库都写都映射
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
其中balance="1"设置为1表示读写分离
<writeHost host="host1" url="192.168.48.10:3306" user="qianyios" password="123456">
<readHost host="host2" url="192.168.48.11:3306" user="qianyios" password="123456" />
这个qianyios用户等等后面会创建
1 | #重启mycat |
在master主节点导入测试的数据库
1 | #全新复制运行即可,要退出mysql,在shell终端运行 |
1 | #在主节点导入 |
在master节点创建用户并对mycat授权
1 | mysql -uroot -p123456 -e "create user 'qianyios'@'192.168.48.%' identified by '123456' ;" |
qianyios
用来给mycat连接本数据库的的账号,映射到前端
在主节点创建好后,由于主从复制,在从节点是可以看得见的
1 | select host,user from mysql.user |
测试读写分离
客户端登入mycat
操作节点:[client]
1 | mysql -u root -p123456 -h192.168.48.128 |
-h192.168.48.128要链接的是mycat的地址
登上了,但是看不了表
一查看报错
1 | [root@mycat ~]# tail -f /apps/mycat/logs/* |
1 | can't connect to mysql server ,errmsg:Client does not support authentication protocol requested by server; consider upgrading MySQL client |
这是由于 MySQL 8 默认使用了新的认证协议 caching_sha2_password
,而 MyCat 客户端可能不支持这种新的认证协议。以下是解决方法:
1 | #在master主节点运行 |
再次重新登入就可以连接了并查看表里
操作节点:[client]
1 | mysql -u root -p123456 -h192.168.48.128 |
验证读写分离
为了确保数据可观,这里要重启一下mycat
操作节点:[mycat]
9066是mycat的管理端口
1 | mycat stop;mycat start; |
目的读和写的信息数是0
开始测试
操作节点:[client]
1 | mysql -uroot -p123456 -h 192.168.48.128 -P 3306 |
回到mycat的状态栏
是不是读的操作就出来了,就是他走的是从节点
接下来验证写操作
操作节点:[client]
1 | mysql> insert into teachers(name,age,gender)values("xiaohu",25,'M'); |
回到mycat的状态栏
是不是一目了然,主节点有了写入的数据,从节点没有
至此读写分离部署成功
模拟从节点宕机
1 | [root@slave ~]# systemctl stop mysqld |
然后里面去客户端进行一次查询
1 | use TESTDB;select * from teachers; |
然后去mycat节点查看状态
这时候从节点宕机之后,客户端会出现几秒钟的查询不到的状态,然后mycat会把请求转向主节点
面试题
mycat是如何检查主从节点存活的
看我的操作,答案在最后
在主从两个节点的my.cnt添加这个
1 | [mysqld] |
general_log
是一个日志系统,用于记录所有由 MySQL 服务器接收到的连接和执行的 SQL 语句。这个日志对于监控数据库操作、分析性能问题、审计和故障排除非常有用。
1 | [root@master ~]# tail -f /data/mysql/master.log |
1 | [root@slave ~]# tail -f /data/mysql/slave.log |
解答:在mycat的/apps/mycat/conf/schema.xml的心跳机制里
mycat就会每10s发送一次select user()去监测主从节点状态
难免会有出错的地方
如果细心的你发现了小失误,可以在下方评论区告诉我,或者私信我!
非常感谢大家的热烈支持!