mycat安装
一、jdk安装
- jdk前往官网下载
- 安装jdk
rpm -ivh jdk-8u231-linux-x64.rpm
- 配置环境变量
[root@master1 ~]# tail -3 /etc/profile
JAVA_HOME=/usr/java/latest
PATH=$JAVA_HOME/bin:$PATH
echo $JAVA_HOME $PARH
[root@master1 ~]# source /etc/profile
[root@master1 ~]# echo $PATH
/usr/java/latest/bin:/usr/java/latest/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@master1 ~]# java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
二、mycat安装
- mycat前往官网下载
- 解压mycat
tar -xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz -C /usr/java/
mycat说明
一、server.xml
server.xml
├───user 标签
│ ├───name #用户名
│ ├───property 标签
│ │ ├───password #密码
│ │ ├───schemas #逻辑数据库名,对应server.xml中schema标签中name
│ │ ├───readOnly #只读模式,取值: true | false
│ │ ├───benchmark #连接阀值,用户的连接超过该值后拒绝连接,0表示不限制
│ │ └───usingDecrypt #对密码加密,取值: 0 | 1
│ └───privileges 标签
│ ├───check #是否检查,取值: true | false
│ └───schema 标签
│ ├───name #用户名
│ ├───dml #insert.update,select,delete 以四位"01"表示
│ └───table 标签
│ ├───name #用户名
│ └───dml #insert.update,select,delete 以四位"01"表示
├───system 标签
│ └───property 标签
│ ├───nonePasswordLogin #连接mysql是否验证,取值: 0 | 1
│ ├───processors #进程数,≤cpu核心数
│ ├───serverPort #服务端口,默认8066
│ ├───managerPort #管理端口,默认9066
│ ├───charset #字符集,mycat和mysql的字符集必一致
│ ├───idleTimeout #mycat会话超时时长
│ ├───bindIp #监听地址,默认0.0.0.0
│ └───sqlExecuteTimeout #sql语句执行超时时长
└───firewall 标签
├───whitehost 标签 #白名单
│ ├───check #是否检查,取值: true | false
│ ├───host #主机 地址或主机名
│ └───user #用户名
└───blacklist 标签 #黑名单
├───check #是否检查,取值: true | false
├───host #主机 地址或主机名
└───user #用户名
二、schema.xml
schema.xml
├───schema 标签
│ ├───name #逻辑数据库名,对应server.xml中user标签的schemas属性
│ ├───dataNode #数据节点,分片信息,也就是分库相关配置
│ ├───checkSQLschema #true时,去掉如select * from db.table中的db。默认false
│ ├───sqlMaxLimit #DQL时默认添加limit,避免查询全表;如果为显示指定MyCat也会自动添加,默认为100。
│ ├───dataNode #逻辑数据节点名,对应dataNode标签中name
│ └───table 标签
│ ├───name #物理数据库中表名
│ ├───primaryKey #物理数据库中表主键字段名
│ ├───dataNode #逻辑数据节点名,对应dataNode标签中name
│ ├───rule #分片规则,对应rule.xml的tableRule标签的name
│ ├───autoIncrement #自增
│ ├───needAddLimit #是否添加对应sqlMaxLimit属性的limit限制,取值 true | false
│ └───childtable 标签
│ ├───name #物理数据库中子表表名
│ ├───primaryKey #物理数据库中子表主键字段名
│ ├───joinKey #物理数据库中子表和父表联接查询字段名
│ ├───parentKey #物理数据库中父表表名
│ └───needAddLimit #是否添加对应sqlMaxLimit属性的limit限制,取值 true | false
├───dataNode 标签
│ ├───name #逻辑数据节点名,对应schema或table标签中的dataNode标签的name
│ ├───dataHost #逻辑数据主机名,对应dataHost标签中name
│ └───database #物理数据库名,对应后端真实数据库
└───dataHost 标签
├───name #逻辑数据主机名,对应dataNode标签中dataHost
├───maxCon #最大连接数
├───minCon #最小连接数
├───balance #读的负载均衡,取值 0 | 1 | 2 | 3
│ # 0 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上
│ # 1 全部的readHost与stand by writeHost参与select语句的负载均衡,
│ #简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),
│ #正常情况下,M2,S1,S2 都参与 select 语句的负载均衡
│
│ # 2 所有读操作都随机的在 writeHost、readhost 上分发
│ # 3 所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力
├───writeType #写入类型,取值, 0 | 1
│ # 0 所有写操作发送到配置的第一个writeHost,
│ #第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准
│
│ # 1 所有写操作都随机的发送到配置的 writeHost,已废弃
├───dbType #数据库类型,只支持mysql
├───dbDriver #数据连接驱动,取值, native | JDBC
├───switchType #切换类型,取值,-1 | 1 | 2 | 3
│ # -1 不自动切换
│ # 1 自动切换
│ # 2 根据heatbeat检测状态决定,语句: show slave status; 适用主从
│ # 3 根据heatbeat检测状态决定,语句: show status like 'wsrep%'; 适用集群
├───slaveThreshold #主从延时切换
├───heartbeat 标签 #心跳检测,一条sql语句
├───writeHost 标签
│ ├───host #逻辑主机名,随便取
│ ├───url #物理数据库地址:数据库端口
│ ├───user #物理数据库用户名
│ ├───password #物理数据库密码
│ ├───weight #权重
│ └───usingDecrypt #对密码加密,取值: 0 | 1
└───readHost 标签
├───host #逻辑主机名,随便取
├───url #物理数据库地址:数据库端口
├───user #物理数据库用户名
├───password #物理数据库密码
├───weight #权重
└───usingDecrypt #对密码加密,取值: 0 | 1
slaveThreshold选项:
MyCAT心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性: switchType=”2” 与 slaveThreshold=”100”,此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制,Mycat心跳机制通过检测 show slave status 中的 “Seconds_Behind_Master”, “Slave_IO_Running”, “Slave_SQL_Running” 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master主从复制时延, 当Seconds_Behind_Master>slaveThreshold时,读写分离筛选器会过滤掉此Slave机器,防止读到很久之前的旧数据,而当主节点宕机后,切换逻辑会检查Slave上的Seconds_Behind_Master是否为0,为0时则表示主从同步,可以安全切换,否则不会切换。
三、rule.xml
rule.xml
├───tableRule 标签
│ ├───name #规则名
│ └───rule 标签 #密码
│ ├───columns #拆分的列
│ └───algorithm #算法,对应function标签的name
└───function 标签
├───name #算法名
└───class #算法的具体类
mycat实验
针对mysql复制中基于gtid的M-M-S-S实现读写分离
- server.xml
......
<user name="mycat" defaultAccount="true">
<property name="password">123</property>
<!-- 逻辑数据库名,为方便识别以真实数据库命名 -->
<property name="schemas">cr</property>
</user>
- schema.xml
......
<schema name="cr" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn" />
<dataNode name="dn" dataHost="masters" database="cr" />
<!-- 因为做的双主双从,balance为1,后端两台slave为只负责读 -->
<!-- writeType为0,前端master只有配置的一台负责写入,另一台备份 -->
<!-- switchType为1,当一台挂掉,另一台备份的起来当主继续工作 -->
<dataHost name="masters" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master1" url="master1:3306" user="mysql" password="123">
<readHost host="slave1" url="slave1:3306" user="mysql" password="123" />
<readHost host="slave2" url="slave2:3306" user="mysql" password="123" />
</writeHost>
<writeHost host="master2" url="master2:3306" user="mysql" password="123">
<readHost host="slave1" url="slave1:3306" user="mysql" password="123" />
<readHost host="slave2" url="slave2:3306" user="mysql" password="123" />
</writeHost>
</dataHost>
- 为了方便查看效果,修改日志记录级别
[root@mycat ~]# grep 'level' /usr/java/mycat/conf/log4j2.xml
<asyncRoot level="debug" includeLocation="true">
- 在物理数据库创建mycat连接用户
#只需在任一台创建即可,会同步到其他3台
grant all privileges on cr.* to 'mysql'@'10.10.10.%' identified by '123';
- 开启mycat
[root@mycat ~]# /usr/java/mycat/bin/mycat start
[root@mycat ~]# jps
6901 Jps
3676 WrapperSimpleApp
[root@mycat ~]# ss -tnl | egrep "8066|9066"
LISTEN 0 100 *:8066 *:*
LISTEN 0 100 *:9066 *:*
- 测试
[root@mycat ~]# mysql -h'mycat' -u'mycat' -p'123' -P'8066'
写入一条数据:
MySQL [cr]> insert into t2 value (100); #master1
MySQL [cr]> insert into t2 value (200); #master1
MySQL [cr]> insert into t2 value (300); #master1
查看全部插入到master2上
查询一条数据:
select * from t2; #slave1
select * from t2; #slave2
select * from t2; #slave1
select * from t2; #slave2