一、什么是Mycat
Mycat是一个开源的分布式数据库系统,但是由于真正的数据库需要存储引擎,而Mycat并没有存储引擎,所以并不是完全意义的分布式数据库系统。
Mycat是目前最流行的基于Java语言编写的数据库中间件,也可以理解为数据库代理。在架构体系中是位于数据库和应用层之间的一个组件,并且对于应用层是透明的,即数据库感受不到mycat的存在,认为是直接连接的mysql数据库(实际上是连接的mycat,mycat实现了mysql的原生协议)Mycat是基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得Mycat变得非常的强大。
Mycat的三大功能:分库分表、读写分离、主从切换。
二、Mycat安装(基于docker)
Mycat安装比较简单,直接官方下载压缩包,解压即可;
官方下载地址:http://dl.mycat.io/
Mycat是java开发的,所以运行Mycat需要jre支持,我们要搞个jre;
这里为了可移植性好,我们自定义docker镜像,写个dockerfile;
1、编写mycatdockerfile文件
FROM centos
MAINTAINER wkj
LABEL name="mycatTest myCat Image" \
build-date="20210126"
ADD server-jre-8u151-linux-x64.tar.gz /home/
ADD Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz /home/
ENV WORKPATH /home/mycat/
WORKDIR $WORKPATH
ENV JAVA_HOME /home/jdk1.8.0_151
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8066
CMD /home/mycat/bin/mycat console
2、创建文件存储
mkdir -p /home/data
上传mycatdockerfile、Mycat-server、jre
3、Mycat启动的两种方式:
bin目录:./mycat console 控制台方式启动(我们用这种,可以看到执行记录信息)
bin目录:./mycat start 后台启动
4、构建docker启动mycat
构建命令:docker build -f mycatdockerfile -t mycatTest/mycat:1.0
5、启动容器
docker run -p 8066:8066 -it 镜像id
6、挂在log和conf,方便更改
重开个窗口
我们先把conf配置和logs日志目录copy到宿主机,主要是我们启动的时候挂载宿主机,方便配置和查看日志;
docker cp 容器Id:/home/mycat/conf/ /home/docker/mycat/
docker cp 容器Id:/home/mycat/logs/ /home/docker/mycat/
7、重新启动mycat
docker stop 容器Id
docker run -p 8066:8066 -it -v /home/docker/mycat/conf/:/home/mycat/conf/ -v /home/docker/mycat/logs/:/home/mycat/logs/ 镜像Id
三、Docker运行两个mysql
1、docker安装mysql
docker pull mysql:5.7
2、挂载
这里我们要搞个操作,方便宿主机修改容器里的配置以及查看日志,我们要搞容器卷,这里首先得把mysql的配置文件和日志目录cp到宿主机;
3、启动mysql,看是否正常
docker run -p 3306:3306 -d -e MYSQL_ROOT_PASSWORD=123456 镜像Id
4、宿主机下home目录下 新建mysql目录,用于存放配置文件和日志目录
mkdir -p /home/mysql
docker cp 容器Id:/etc/mysql/mysql.conf.d/ /home/mysql/
docker cp 容器Id:/var/log /home/mysql/
5、停止所有启动的mysql,然后挂载启动两个容器
docker run -p 3306:3306 --name master -d -v /home/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql/log/:/var/log -e MYSQL_ROOT_PASSWORD=123456 镜像ID
docker run -p 3307:3306 --name master -d -v /home/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql/log/:/var/log -e MYSQL_ROOT_PASSWORD=123456 镜像ID
四、docker实现容器自定义IP地址
我们在使用Docker容器时候,每次启动容器,容器分配到的虚拟IP经常变动,比如我们现在使用Mycat+Mysql,我们是需要配置Mysql服务IP地址的,这个IP是Docker分配的虚拟IP,假如老是变,那我们还得老是修改配置,那就很麻烦了;所以我们需要固定手工分配容器IP;
docker默认使用的是bridge桥接网络模式,我们可以查看下docker network ls
1、创建自定义网络模式
docker network create --subnet=172.20.0.0/16 extnetwork
2、创建容器并指定IP
通过--net extnetwork --ip 172.20.0.2 指定
3、启动两个mysql服务
我们启动两个Mysql容器,并且固定分配IP 172.20.0.2和172.20.0.3
(注意:这里必须用172.20.0.2开始分配,因为172.20.0.1是网关;)
docker run -p 3306:3306 --name master -d -v /home/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql/log:/var/log --net extnetwork --ip 172.20.0.2 -e MYSQL_ROOT_PASSWORD=123456 镜像Id
docker run -p 3306:3306 --name master -d -v /home/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql/log:/var/log --net extnetwork --ip 172.20.0.2 -e MYSQL_ROOT_PASSWORD=123456 镜像Id
docker inspect 容器Id
4、扩展
docker network rm extnetwork #删除网络
docker rm -f $(docker ps -qa) #删除所有容器
五、主从复制配置
现在Mysql主服务器 172.20.0.2 从服务器 172.20.0.3
1、配置主服务器
打开mysqld.cnf:
添加如下配置:
# 主服务器ID 必须唯一
server-id=2
# 开启及设置二进制日志文件名称
log_bin=mysql-bin
# 要同步的数据库
binlog-do-db=db_mycatTest
# 不需要同步的数据库
binlog-ignore-db=mysql
binlog_ignore_db=information_schema
binlog_ignore_db=performation_schema
binlog_ignore_db=sys
# 设置logbin格式
binlog_format=MIXED # binlog日志格式,mysql默认采用statement,建议使用mixed
2、从服务器
打开mysqld.cnf:
server-id=3
relay-log=mysql-relay
3、主服务器创建从机访问用户以及授权
CREATE USER 'slave1'@'172.20.0.3' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave1'@'172.20.0.3';
FLUSH PRIVILEGES;
4、查看主服务器状态
SHOW MASTER STATUS
5、从机创建连接主服务器的IP,用户,密码以及日志文件和位置
CHANGE MASTER TO MASTER_HOST='172.20.0.2', MASTER_USER='slave1', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;
6、启动主从复制
START SLAVE
7、查看从机状态
SHOW SLAVE STATUS
有两个yes才OK
假如有NO活着Connecting,请看下方日志或者找到Mysql日志文件查看具体问题;
8、binlog_format详解
mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED。
① STATEMENT模式(SBR)
每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
② ROW模式(RBR)
不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table的时候会让日志暴涨。
③ MIXED模式(MBR)
以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。
九、主从复制实现常用命令
1、START SLAVE
不带任何参数,表示同时启动I/O 线程和SQL线程。
I/O线程从主库读取bin log,并存储到relay log中继日志文件中。
SQL线程读取中继日志,解析后,在从库重放。
2、STOP SLAVE
完成停止I/O 线程和SQL线程的操作。
3、SHOW MASTER STATUS
查看主服务器状态
4、SHOW SLAVE STATUS
查看从服务器状态
5、REST MASTER
删除所有index file 中记录的所有binlog 文件,将日志索引文件清空,创建一个新的日志文件,这个命令通常仅仅用于第一次用于搭建主从关系的时的主库,
十、Mycat读写分离
schema.xml有几个标签,分别是:mycat:schema schema主配置标签, schema逻辑库配置标签,dataNode数据节点配置标签,dataHost数据库主机配置标签;
一个逻辑库,对应多个逻辑表,每个逻辑表如上图,可以水平分片(我们后面会细讲),分成一个或者多个数据分片节点,每个数据分片节点对应一个dataHost(数据库主机),dataHost里可以通过writeHost和readHost配置写主机和读主机;
1、绑定容器IP地址启动mycat
docker run -p 8066:8066 -it -v /home/docker/mycat/conf/:/home/mycat/conf/ -v /home/docker/mycat/logs/:/home/mycat/logs/ --net extnetwork --ip 172.20.0.4 镜像id
2、更改 /home/docker/mycat 中的schema.xml文件
参考配置(主从,读写分类):
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db_java1234" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="masterHost1" url="172.20.0.2:3306" user="root"
password="123456">
<readHost host="slaveHost1" url="172.20.0.3:3306" user="root"
password="123456"></readHost>
</writeHost>
</dataHost>
</mycat:schema>
3、schema标签属性介绍:(定义逻辑数据库)
4、dataNode标签属性:(定义数据分片节点)
5、dataHost标签属性:(定义后端的数据库主机)
6、 heartbeat子标签属性(心跳执行SQL)
writeHost子标签属性(写主机配置)
readHost子标签属性(读主机配置)
十一、mysql+mycat双主双从
M1 S1 主从复制 M2 S2 主从复制; M1,M2 互为主从复制 实现数据同步;无论哪个挂掉,Mycat可以自动切换,依然系统可用;
1、复制配置文件
m1 为 mysql,m2为mysql3
s1为mysql2,s2为mysql4
2、更改配置文件内容
m1,m2我们要加配置:涉及到数据插入id不冲突,以及数据同步;
# 在作为从数据库的时候,有写入操作也要更新二进制日志文件
log-slave-updates
#表示自增长字段每次递增的量,指自增字段的起始值,其默认值是1,取值范围是1 .. 65535
auto-increment-increment=2
# 表示自增长字段从哪个数开始,指字段一次递增多少,他的取值范围是1 .. 65535
auto-increment-offset=1(m1配置)
auto-increment-offset=2(m2配置)
s2的其他不用更改,只需要 server-id=6
3、启动四个mysql服务器
docker run -p 3306:3306 --name master -d -v /home/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql/log/:/var/log --net extnetwork --ip 172.20.0.2 -e MYSQL_ROOT_PASSWORD=123456 镜像ID
docker run -p 3307:3306 --name slave -d -v /home/mysql2/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql2/log/:/var/log --net extnetwork --ip 172.20.0.3 -e MYSQL_ROOT_PASSWORD=123456 镜像ID
docker run -p 3308:3306 --name master2 -d -v /home/mysql3/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql3/log/:/var/log --net extnetwork --ip 172.20.0.5 -e MYSQL_ROOT_PASSWORD=123456 镜像ID
docker run -p 3309:3306 --name slave2 -d -v /home/mysql4/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql4/log/:/var/log --net extnetwork --ip 172.20.0.6 -e MYSQL_ROOT_PASSWORD=123456 镜像ID
4、重新授权
m1 删除user里的原先slave用户,重新权;
CREATE USER 'slave'@'172.20.0.%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'172.20.0.%';
FLUSH PRIVILEGES;
RESET MASTER
s1 配置主从复制;
CHANGE MASTER TO MASTER_HOST='172.20.0.2', MASTER_USER='slave', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;
START SLAVE
SHOW SLAVE STATUS
m2 创建slave用户,授权
CREATE USER 'slave'@'172.20.0.%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'172.20.0.%';
FLUSH PRIVILEGES;
RESET MASTER
s2 配置主从复制;
CHANGE MASTER TO MASTER_HOST='172.20.0.5', MASTER_USER='slave', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;
START SLAVE
SHOW SLAVE STATUS
5、配置双主 主从复制
m2复制m1配置;
m1先reset
RESET MASTER
m2里配置:
CHANGE MASTER TO MASTER_HOST='172.20.0.2', MASTER_USER='slave', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;
START SLAVE
SHOW SLAVE STATUS 测试;
m1复制m2配置;
m2先rest
RESET MASTER
m1里配置:
CHANGE MASTER TO MASTER_HOST='172.20.0.5', MASTER_USER='slave', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;
START SLAVE
SHOW SLAVE STATUS 测试;
6、双主双从读写分离配置
以及balance要搞成1 现在是双主双从;
balance="1",全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。