Docker容器 - 实现MySQL主从复制 + 读写分离(Docker + MySQL + MyCat)

14 篇文章 3 订阅
1 篇文章 0 订阅

目录

一、主从复制 

新建主服务器容器实例3307

进入/mydata/mysql-master/conf新建my.cnf

修改完配置后重启master实例

进入mysql-master容器

master容器实例内创建数据同步用户

新建从服务器容器实例3308

进入/mydata/mysql-slave/conf新建my.cnf

修改完配置后重启slave实例

在主数据库中查看主从同步状态

进入mysql-slave容器

在从数据库中配置主从复制

在从数据库中查看主从同步状态

在从数据库中开启主从同步

再次查看从数据库状态

二、主从复制测试

主数据库

从数据库

三、读写分离

Docker安装MyCat

server.xml 

schema.xml 

sequence_conf.properties 

rule.xml

运行容器

容器中安装JDK

连接测试


使用Docker安装MySQL5.7的详细文章:Linux中使用Docker安装MySQL5.7(CentOS7)_不会调制解调的猫的博客-CSDN博客

一、主从复制 

新建主服务器容器实例3307

这里就算没有拉取mysql5.7的镜像也可以直接运行,若发现没有镜像则会直接自动拉取。

这里的-v如果不懂,也可以查看之前的容器数据卷详解:Docker容器数据卷_不会调制解调的猫的博客-CSDN博客

docker run -p 3307:3306 --name mysql-master -v /mydata/mysql-master/log:/var/log/mysql -v /mydata/mysql-master/data:/var/lib/mysql -v /mydata/mysql-master/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

 ps查看一下,确认它起来了

docker ps


进入/mydata/mysql-master/conf新建my.cnf

vim /mydata/mysql-master/conf/my.cnf

直接把以下内容全部复制粘贴进去,然后保存退出。 

[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=101 
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql  
## 开启二进制日志功能
log-bin=mall-mysql-bin  
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M  
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed  
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7  
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062

修改完配置后重启master实例

在宿主机上通过容器数据卷来修改配置,传导给docker内部,是需要重启的

docker restart mysql-master 

再ps查看一下,要确认它已经up起来了

docker ps


进入mysql-master容器

docker exec -it mysql-master /bin/bash
mysql -uroot -proot

容器进入成功,继续下一步


master容器实例内创建数据同步用户

安全加固,添加一个用户,然后授权

create user 'slave'@'%' identified by '123456';
grant replication slave,replication client on *.* to 'slave'@'%';


新建从服务器容器实例3308

docker run -p 3308:3306 --name mysql-slave -v /mydata/mysql-slave/log:/var/log/mysql -v /mydata/mysql-slave/data:/var/lib/mysql -v /mydata/mysql-slave/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

ps以确认其up 


进入/mydata/mysql-slave/conf新建my.cnf

vim /mydata/mysql-slave/conf/my.cnf

直接粘贴然后保存退出

[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql  
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin  
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M  
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed  
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7  
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062  
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin  
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1  
## slave设置为只读(具有super权限的用户除外)
read_only=1

修改完配置后重启slave实例

docker restart mysql-slave


在主数据库中查看主从同步状态

show master status;


进入mysql-slave容器

docker exec -it mysql-slave /bin/bash
mysql -uroot -proot


在从数据库中配置主从复制

是在从数据库配置,不是主!

change master to master_host='宿主机ip', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;

change master to master_host='192.168.150.30', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;

参数说明:

master_host:主数据库的IP地址;

master_port:主数据库的运行端口;

master_user:在主数据库创建的用于同步数据的用户账号;

master_password:在主数据库创建的用于同步数据的用户密码;

master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;

master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;

master_connect_retry:连接失败重试的时间间隔,单位为秒。


在从数据库中查看主从同步状态

show slave status \G

\G 是竖着来查看,有点类似于键值对

这里的Slave_IO_Running和Slave_SQL_Running都还是NO,没有启动


在从数据库中开启主从同步

start slave;


再次查看从数据库状态

show slave status \G

 成功。


二、主从复制测试

主数据库

主数据库新建库,新建表,插入数据

create database dbtest1;
use dbtest1;
create table test1 (id int,name varchar(20));
insert into test1 values(1,'van');
select * from test1;


从数据库

从数据库进行查找

show databases;
use dbtest1;
select * from test1;

 测试成功!


三、读写分离

Docker安装MyCat

拉取MyCat镜像:

docker pull longhronshens/mycat-docker

创建目录并配置文件:

mkdir -p /usr/local/mycat
cd /usr/local/mycat

server.xml 

vim  /usr/local/mycat/server.xml

将以下内容复制进去:

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
	- you may not use this file except in compliance with the License. - You 
	may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
	- - Unless required by applicable law or agreed to in writing, software - 
	distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
	License for the specific language governing permissions and - limitations 
	under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
	<system>
	<property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
	<property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->
		<property name="sequnceHandlerType">0</property>
		<property name="processorBufferPoolType">0</property>
		<!--默认是65535 64K 用于sql解析时最大文本长度 -->
		<!--<property name="maxStringLiteralLength">65535</property>-->
		<!--<property name="sequnceHandlerType">0</property>-->
		<!--<property name="backSocketNoDelay">1</property>-->
		<!--<property name="frontSocketNoDelay">1</property>-->
		<!--<property name="processorExecutor">16</property>-->
		<!--
			<property name="serverPort">8066</property> <property name="managerPort">9066</property> 
			<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property> 
			<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
		<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
		<property name="handleDistributedTransactions">0</property>
			<!--
			off heap for merge/order/group/limit      1开启   0关闭
		-->
		<property name="useOffHeapForMerge">1</property>
		<!--
			单位为m
		-->
		<property name="memoryPageSize">1m</property>
		<!--
			单位为k
		-->
		<property name="spillsFileBufferSize">1k</property>
		<property name="useStreamOutput">0</property>
		<!--
			单位为m
		-->
		<property name="systemReserveMemorySize">384m</property>
		<!--是否采用zookeeper协调切换  -->
		<property name="useZKSwitch">true</property>
	</system>
	<user name="root">
		<property name="password">root</property>
		<property name="schemas">test</property>
	</user>
</mycat:server>

schema.xml 

vim  /usr/local/mycat/schema.xml

继续复制:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
	<schema name="test" checkSQLschema="false" sqlMaxLimit="100">
		<table name="tb_user"   primaryKey="id"  autoIncrement="true"  dataNode="dn1,dn2,dn3,dn4" rule="userrule" />
		<table name="tb_category" primaryKey="id" dataNode="dn1,dn2,dn3,dn4" rule="categoryrule" />
	</schema>
	<dataNode name="dn1" dataHost="localhost1" database="db1" />
	<dataNode name="dn2" dataHost="localhost1" database="db2" />
	<dataNode name="dn3" dataHost="localhost1" database="db3" />
	<dataNode name="dn4" dataHost="localhost1" database="db4" />
	<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<writeHost host="hostM1" url="192.168.21.55:3307" user="root"
				   password="root">
			<readHost host="hostS2" url="192.168.21.55:3308" user="root" password="root" />
		</writeHost>
	</dataHost>
</mycat:schema>


sequence_conf.properties 

vim  /usr/local/mycat/sequence_conf.properties
TB_USER.HISIDS=
TB_USER.MINID=1
TB_USER.MAXID=20000
TB_USER.CURID=1

rule.xml

vim  /usr/local/mycat/rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
	<tableRule name="userrule">
		<rule>
			<columns>id</columns>
			<algorithm>func1</algorithm>
		</rule>
	</tableRule>
	<tableRule name="categoryrule">
		<rule>
			<columns>id</columns>
			<algorithm>jump-consistent-hash</algorithm>
		</rule>
	</tableRule>

	<function name="murmur"
		class="io.mycat.route.function.PartitionByMurmurHash">
		<property name="seed">0</property><!-- 默认是0 -->
		<property name="count">2</property><!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
		<property name="virtualBucketTimes">160</property><!-- 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍 -->
		<!-- <property name="weightMapFile">weightMapFile</property> 节点的权重,没有指定权重的节点默认是1。以properties文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替 -->
		<!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> 
			用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西 -->
	</function>

	<function name="crc32slot"
			  class="io.mycat.route.function.PartitionByCRC32PreSlot">
		<property name="count">2</property><!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
	</function>
	<function name="hash-int"
		class="io.mycat.route.function.PartitionByFileMap">
		<property name="mapFile">partition-hash-int.txt</property>
	</function>
	<function name="rang-long"
		class="io.mycat.route.function.AutoPartitionByLong">
		<property name="mapFile">autopartition-long.txt</property>
	</function>
	<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<property name="count">4</property>
	</function>

	<function name="func1" class="io.mycat.route.function.PartitionByLong">
		<property name="partitionCount">8</property>
		<property name="partitionLength">128</property>
	</function>
	<function name="latestMonth"
		class="io.mycat.route.function.LatestMonthPartion">
		<property name="splitOneDay">24</property>
	</function>
	<function name="partbymonth"
		class="io.mycat.route.function.PartitionByMonth">
		<property name="dateFormat">yyyy-MM-dd</property>
		<property name="sBeginDate">2015-01-01</property>
	</function>
	
	<function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
        	<property name="mapFile">partition-range-mod.txt</property>
	</function>
	
	<function name="jump-consistent-hash" class="io.mycat.route.function.PartitionByJumpConsistentHash">
		<property name="totalBuckets">4</property>
	</function>
</mycat:rule>

运行容器

docker run --name mycat -v /usr/local/mycat/schema.xml:/usr/local/mycat/conf/schema.xml -v /usr/local/mycat/rule.xml:/usr/local/mycat/conf/rule.xml -v /usr/local/mycat/server.xml:/usr/local/mycat/conf/server.xml -v /usr/local/mycat/sequence_conf.properties:/usr/local/mycat/conf/sequence_conf.properties --privileged=true -p 8066:8066 -p 9066:9066 -e MYSQL_ROOT_PASSWORD=root  -d longhronshens/mycat-docker 

容器中安装JDK

将JDK的安装包传到容器内,格式为:

docker cp 宿主机内目录 容器ID:容器内目录

举个栗子:

docker cp /opt/software/jdk-8u201-linux-x64.rpm fe5162fd39ea:/

进入容器:

docker exec -it mycat bash

 解压安装:

rpm -ivh jdk-8u201-linux-x64.rpm

使用yum安装vim: 

yum install -y vim

修改配置文件:

vim /etc/profile.d/java.sh

将以下内容复制进去:

export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$PATH

保存退出后source一下:

source /etc/profile

Ctrl+D退出,然后重启容器:

docker restart mycat

连接测试

进入MySQLMaster容器:

docker exec -it mysql-master bash
mysql -h192.168.150.30 -uroot -proot -P8066

打开Navicat进行连接,注意端口号 :

连接成功

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会调制解调的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值