Mycat是轻量级mysql读写分离中间件,使用java语言开发
环境转变:搭好的主从结构mysql。安装好必要的各种依赖。
主从参考:https://blog.csdn.net/VegetandBird_s/article/details/102712633
0.准备工作
本文案例
mysql主MASTER IP=10.1.1.28
mysql主SLAVE IP=10.1.1.34
# 待会先要用到一个数据库名,也就是请先建立一个要使用的数据库。
mysql> CREATE DATABASE IF NOT EXISTS 数据库名称 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
# 还需要授予访问数据库的用户以远程访问权限,root处可以自定义,本文以root为例
mysql> grant all on *.* to 'root'@'%' identified by '123';flush privileges;
1.下载java环境
官网指路:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
版本:
Linux x64 | 185.16 MB | jdk-8u231-linux-x64.tar.gz |
注:这个下载地址不保证直接能用,常规节奏是进入Oracle官网进行点击下载(还要求注册Oracle会员),然后用ftp上传服务器。
如果好使,可以直接在shell里wget它。本文是进行了Oracle会员注册后,再shell中就可以下载了。不知道这个注册是不是影响了下载能力。
2.安装Java环境
以本文为例,我们按照管理将文件jdk-8u231-linux-x64.tar.gz下载到/software文件夹中。
# 本文以jdk-8u192版本为例
# cd /software
# tar xvf jdk-8u192-linux-x64.tar.gz
# mkdir /usr/local/java
# mv /software/jdk1.8.0_192 /usr/local/java/
# 建立一个/usr/local/的java专用文件夹,因为java环境版本繁杂,为以后可能进行的版本拓展,将所有java文件放在专用文件夹下,并以版本区分
# 将java加入环境变量。
# echo "export PATH=\$PATH:/usr/local/java/jdk1.8.0_192/bin" >> /etc/profile
# source /etc/profile
3.下载安装Mycat
Mycat是绿色版软件,下载,解压,放在正确的位置即可。
# cd /software
# wget http://dl.mycat.io/1.6.7.3/20190927161129/Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz
# tar xvf Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz
# mv mycat /usr/local/
测试
# /usr/local/mycat/bin/mycat start
# ss -nltp
# /usr/local/mycat/bin/mycat stop
# ss -nltp
# 进程中会出现一堆java项,视为成功。
1.报错:Ignoring option MaxPerSize:support was removed in 8.0
# vim conf/wrapper.conf
# wrapper.startup.timeout=300 ==> 添加这一行
# wrapper.ping.timeout=120 ==> 默认存在
2.报错:Unable to start JVM: No such file or directory (2)
# 前面未加入环境变量,或未重载环境变量
3.报错内存不足
jvm 1 | Invalid maximum heap size: -Xmx4G
jvm 1 | The specified size exceeds the maximum representable size.
jvm 1 | Error: Could not create the Java Virtual Machine.
jvm 1 | Error: A fatal exception has occurred. Program will exit.
# vi /usr/local/mycat/conf/wrapper.conf
# 修改这两行
wrapper.java.additional.10=-Xmx4G (大约在36行)
wrapper.java.additional.11=-Xms1G
# 4G变512M,1G变256M,大概这样。
4.配置Mycat
重点文件:schema.xml
# vi /usr/local/mycat/conf/schema.xml
# 精简策略
# 1.删除所有注释标签
# 2.<schema ...>内容可以清空</schema>
# 3.dn2,dn3可以删掉
# 4.删掉<writeHost host="hostS1" ... >
修改:
1.<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode='节点名'>
处理:修改标签,加入属性 dataNode='节点名'
2.<dataNode name="dn1" dataHost="localhost1" database="数据库名称" />
处理:节点名就是dataNode标签里的name属性值,将database属性改为咱们真实的数据库名
3.<dataHost ... balance="1" ...>
处理:将dataHost标签的balance改为1,代表开启读写分离。0表示不开启。
4.<writeHost host="hostM1" url="10.1.1.33:3306" user="root" password="123">
处理:修改writeHost标签中的,url,user,password,为写数据库
5.<readHost host="hostS1" url="10.1.1.34:3306" user="root" password="123">
处理:修改writeHost标签中的,url,user,password,为读数据库
这里注意,mysql远程登录,需要给登录用户赋予权限,比如这个root。这就是前文授权的意义,再次提醒
授权语句是
mysql> grant all on *.* to 'root'@'%' identified by '123';flush privileges;
IP段请自定义
并且上面填的'数据库名称',要在主从mysql机器里存在这个数据库。
再
# vi /usr/local/mycat/conf/server.xml
有一段内容是这样
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
它规定了三个数据,root,123456,TESTDB,分别是mycat生成的虚拟mysql的用户名密码和数据库名,可以自定义
配置完重启
# /usr/local/mycat/bin/mycat restart
或
# /usr/local/mycat/bin/mycat stop
# /usr/local/mycat/bin/mycat start
# ss -nltp
# 等十几秒后,占用8066与9066即为成功
5.使用mycat虚拟数据库
# 开启mycat服务后,占用了8066号9066端口。
# 登录mycat服务所在IP的mysql,端口号9066 用户root 密码123456(前文有)
# mysql -h 10.1.1.28 -P 9066 -u root -p
# 9066端口是mycat的管理端
# 输入命令,开启帮助页面。
mysql> show @@help;
# 查看mycat管理的读写mysql状态。
mysql> show @@heartbeat;
列表中RS_CODE=1,为连接正常。
# 登录mycat服务所在IP的mysql,端口号8066 用户root 密码123456(前文有)
# mysql -h 10.1.1.28 -P 8066 -u root -p
# 8066端口是mycat的客户端,好比一个正常的mysql
mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
# 数据库列表显示存在一个库,是前文说到的,TESTDB。前文自定义的话,这里就会变化。
mysql> show tables;
# 就会显示出那个 '数据库名称' 里的所有表喽。
6.验证测试
# 修改日志的配置文件
# vi /usr/local/mycat/conf/log4j2.xml
<asyncRoot level="info" includeLocation="true">
将info,修改成debug,保存重启服务
# /usr/local/mycat/bin/mycat restart
# 关注mycat的日志文件。
# echo '' > /usr/local/mycat/conf/mycat.log
# tail -f /usr/local/mycat/conf/mycat.log
# 然后我们对数据库进行写操作
# 写操作:insert into tb_word (content,day) values ('b','1');
2019-11-13 07:46:35.064 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:386)) - release connection MySQLConnection [id=5, lastTime=1573620394899, user=root, schema=MKtaobao, old shema=MKtaobao, borrowed=true, fromSlaveDB=false, threadId=30, charset=utf8, txIsolation=3, autocommit=true, attachment=dn1{insert into tb_word (content,day) values ('b','1')}, respHandler=SingleNodeHandler [node=dn1{insert into tb_word (content,day) values ('b','1')}, packetId=1], host=10.1.1.28, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
# 显示执行host是10.1.1.28,正是我的写机
# 写操作:select * from tb_word;
2019-11-13 07:47:31.310 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:386)) - release connection MySQLConnection [id=13, lastTime=1573620451296, user=root, schema=MKtaobao, old shema=MKtaobao, borrowed=true, fromSlaveDB=true, threadId=17, charset=utf8, txIsolation=3, autocommit=true, attachment=dn1{select * from tb_word}, respHandler=SingleNodeHandler [node=dn1{select * from tb_word}, packetId=8], host=10.1.1.34, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
# 显示执行host是10.1.1.34,正是我的读机
成功
7. dataHost的参数
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
# name=节点主机名称
# maxCon=指定每个读写实例连接池的最大连接
# minCon=指定每个读写实例连接池的最小连接,即初始化连接池的大小
# dbType=指定连接的数据库类型,例如mysql、mongodb、oracle、spark等
# dbDriver=数据库的驱动,为native和JDBC。native支持mysql和mariadb,其他数据库需要用JDBC驱动
# writeType=写操作负载均衡类型,目前有四个可选值”0”、”1”、”2”。
0,所有写操作都发送到可用的writeHost上。
1,所有写操作都随机的发送到readHost。
2,所有写操作都随机的在writeHost、readhost分上发。
# balance=读操作负载均衡类型,目前有四个可选值”0”、”1”、”2”、”3”。
0,代表不开启读写分离,读操作都发到writeHost上。
1,所有读操作都随机发送到当前的writeHost对应的readHost和备用的writeHost。(常规设置值)
2,代表所有的读操作都随机发送到所有的writeHost,readHost上。
3,所有的读操作都只发送到writeHost下属的readHost上。
# switchType=宕机切换模式,四个可选值”-1”、”1”、”2”、”3”。
-1:表示不启用主从切换;
1:为默认值,自动切换;
2:基于主从同步的状态,决定是否切换,需要修改<heartbeat>show slave status</heartbeat>
3:基于多住galary集群切换,需要修改<heartbeat>show status like 'wsrep%'</heartbeat>
# slaveThreshold=是switchtype的附属参数,网络上查到的没有解释,翻译过来是指'从机的门槛',可能是那个权重值。大于这个属性值才会优先被切换,资料不足。默认值=100
# tempReadHostAvailable:自主添加,writeHost失联后,其下面的readHost仍旧可用,默认0,可选值0、1