Mycat02(Mysql主从复制 一主一从) 读写分离
参考:http://47.100.191.44/blog/articles/409
1、通过docker 安装mysql mysql是Master mysql1是Slave
启动容器用通过mysql 连接工具测试连接。
配置Master(mysql)
docker exec -it 容器名(或者id) /bin/bash
切换到/etc/mysql目录下,使用 vim命令编辑my.cnf文件,会出现 bash:vim:command not fount ,需要安装vim工具
docker内部安装vim
很简单,依次输入如下命令即可安装,时间和网速有关,耐心等待。
apt-get update apt-get install vim
也可以通过挂载的方式在宿主机里面修改。
[mysqld] ## 同一局域网内注意要唯一 server-id=1 #开启二进制日志功能,可以随便取(关键) log-bin=mysql-bin #不需要同步的库 binlog-ignore-db=mysql binlog-do-db=数据库名 binlog-format=STATEMENT
配置完成后,需要重启mysql服务使其修改的配置文件生效,使用如下命令使mysql进行重启
service mysql restart
重启会导致docker容器停止,使用命令重启容器
docker start 容器名(或者容器id)
创建数据库同步账户
使用docker命令进入Master容器内部:
docker exec -it 容器名(或者容器id)/bin/bash
在Master数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。登录到mysql客户端:
mysql -uroot -p123
创建用户并授权:
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Master 配置完成。
配置Slave(mysql1)
类似于Master ,使用docker命令进入到 slave 容器中,并进入到/etc/mysql路径,使用vim命令编辑my.cnf 文件:
[mysqld] server-id=2 relay-log=mysql-relay
配置完成后也需要重启mysql服务和docker容器,操作可以参考Master。
开启Master-Slave主从复制
进入Master库mysql 客户端:输入 **show master status;**查看Master状态:
记住File和Position,后面需要用到。此时一定不要操作Master库,否则将会引起Master状态的变化,File和Position字段也将会进行变化。
进入到Slave库myslq客户端,执行如下命令:
change master to master_host='172.17.0.4', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000002', master_log_pos=154, master_connect_retry=30;
如果出现错误(重新配置主从):
#使用
stop slave;
reset master;
命令说明:
master_host :Master库的地址,指的是容器的独立ip,可以通过
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称 | 容器id查询容器的IP进行查询:
也可以通过docker的自定义网络配置容器ip
master_port:Master的端口号,指的是容器的端口号
master_user:用于数据同步的用户
master_password:用于同步的用户的密码
master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
在Slave 中的mysql终端执行 show slave status \G; 用于查看主从同步状态:
下面是正常的,中间可能出现的问题:
问题一:这个地方如果是两个NO
Slave_IO_Running 和 Slave_SQL_Running是查看主从是否运行的关键字段,默认为NO,表示没有进行主从复制。
使用 start slave; 开启主从复制过,然后再次查询主从同步状态:show slave status \G;
问题二:如果上面一个为Connecting,下面一个为YES.
使用 start slave; 开启主从复制过程后,如果SlaveIORunning一直是Connecting,则说明主从复制一直处于连接状态,这种情况一般是下面几种原因造成的,我们可以根据 Last_IO_Error提示予以排除。
1、网络不通:检查ip,端口 2、密码不对:检查是否创建用于同步的用户和用户密码是否正确 3、pos不对:检查Master的 Position
正常启动后如上图所示。
Slave_IO_Running和 Slave_SQL_Running 都是 YES,说明复制已经开始,可以测试数据是否同步成功。
mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.17.0.4 Master_User: slave Master_Port: 3306 Connect_Retry: 30 Master_Log_File: mysql-bin.000002 Read_Master_Log_Pos: 154 Relay_Log_File: mysql-realy.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 154 Relay_Log_Space: 523 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: d0d6b6db-2345-11eb-a4ad-0242ac110002 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec)
接下来只需要在Master 中建一个testdb的库然后创建表,在Slave查看是否同步。
Mycat读写分离
首先修改配置文件也就是cjh_docker/mycat/conf/schema.xml
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> </schema> <dataNode name="dn1" dataHost="localhost1" database="testdb" /> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts -->// url 是容器端口 <writeHost host="hostM1" url="172.17.0.4:3306" user="root" password="123"> <!-- can have multi read hosts --> <readHost host="hostS2" url="172.17.0.3:3306" user="root" password="123" /> </writeHost> <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </dataHost> </mycat:schema>
验证读写分离:
#1.在Master里面插入: insert into mytbl values(1,@@hostname);#@@hostname表示系统变量(这里是容器id) #2.在mycat 里面查询:select * from mytbl;
发现并未实现读写分离。
修改<dataHost> 的 balance属性,通过这个属性配置读写分离的类型。
#负载均衡类型,目前有4种: 1、balance="0",不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。 2、balance="1",全部的readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,且M1与M2互为主备),正常情况下,M2,S1,S2都参与Select语句的负载均衡。 3、balance="2" ,所有读操作都随机的在writeHost、readHost上分发。 4、balance="3", 所有读请求随机的分发到readHost执行,writeHost不负担读压力。
为了能看到读写分离的效果,把balance设置成3 就行了
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">