使用Docker搭建一主一从的MySQL集群,使用的是8版本的MySQL镜像,如果不是8的版本部分本文里的部分命令会无效,宿主机系统任意。一主一从与一主多从流程相同,只是多了几个容器,需要与master多连接几次
规划
端口 | 角色 |
---|---|
3307 | master |
3308 | slave |
思路
事先准备
要确保linux宿主机已经安装上Docker。然后将MySQL镜像下载到本地 ,可以先去Docker Hub上寻找对应的版本,然后将对应版本的下载命令在宿主机复制,最后等待下载完成。
外部搭建
-
获取MySQL的配置文件
可以随意的先启动的一台MySQL容器,然后将/etc目录下的内容复制到宿主机,这样便于修改。
例如:在家目录下创建一个文件夹etc3307/
,然后使用命令docker cp MySQL容器Id/etc/ ~/etc3007/
这时,此目录下就会有一个MySQL的配置文件信息。 -
修改MySQL配置文件
- 复制配置文件:将
etc3307
目录进行复制cp -r ~etc3307/ ~/etc3308/
,这时家目录下就会出现两个目录,ect3307
目录下的配置文件用来作为master的配置,etc3308
目录用来做slave下的配置 - 使用vim修改配置两个目录中的
my.cnf
,在[mysqld]
的下方加上如下内容 注意不同之处!#[必须]从服务器唯一ID 数字任意,各个主机间id不能相同!!! server-id=1 #[可选] 0(默认)表示读写(主机),1表示只读(从机) read-only=0
- 复制配置文件:将
-
启动容器,挂载宿主机目录
开启主机3307
docker run --name mysql-master --privileged=true -v ~/etc3307/:/etc/ -p 3307:3306 -e MYSQL_ROOT_PASSWORD=你的主机密码 -d 镜像id
开启从机3308
docker run --name mysql-slave --privileged=true -v ~/etc3308/:/etc/ -p 3308:3306 -e MYSQL_ROOT_PASSWORD=你的从机密码 -d 镜像id
- 创建网络,使两个容器内部能够相互访问 。注意:容器之间访问端口都是3306
- 创建网络
docker network inspect my-bridge
(my-bridge是是自定义的名字) - 将容器加入网络
docker network connect my-bridge mysql-slave
,docker network connect my-bridge mysql-master
分别是将从机加入网络、将主机加入网络 。命令的格式为docker network connect 网络名 容器名
- 使用命令
docker network inspect my-bridge
查看是否加入成功
此时外部环境搭建已经完成,当前两台MySQL各自能够独立运行,容器内部能够相互访问,配置文件中server-id不同,
内部配置
建立两个SQL服务的主从联系
- 连接两个MySQL服务器(注意防火墙),当然,使用
docker exec -it 容器id /bin/bash
进入各自容器内部使用命令行连接也可以。
主机3307配置:
--执行以下命令
-- 创建一个专门用来在从服务器使用从而复制主服务器数据的用户
CREATE USER '用户名'@'%' IDENTIFIED WITH mysql_native_password BY '用户密码';
-- 为此用户授予REPLICATION权限
GRANT REPLICATION SLAVE ON *.* TO '此用户名'@'%';
-- 刷新
flush privileges;
然后在查看一下自己当前的binlog日志状态 show master status;
记住要复制的文件和起始位置
从机3308配置:
1.
--执行以下命令
CHANGE REPLICATION SOURCE TO SOURCE_HOST='mysql-master', SOURCE_USER='用户名', SOURCE_PASSWORD='次用户密码', SOURCE_LOG_FILE='上面要记住的主机日志文件 binlog.000003', SOURCE_LOG_POS=上面要记住的起始位置335;
-- 开启从模式,连接主机master
start replica ;
- 查看连接状态(是否配置成功)
show replica status ;
有问题可以使用docker logs 容器id
查看对应的日志报错信息,就知道出错在哪里。
到此搭建完成,在主机任何写操作都会立即同步到从机
注意:
- 如果没有设置从机只读,那么从机依然可以写入,但主机写入会同步给从机,从机写入不会同步主机
- 主机一但宕机,整个主从集群将都不能写入。不存在像Redis主从集群那样可以类似于哨兵机制进行监测,master宕机slave顶上的情况。单主多从达不到高可用效果。
- 如果想要实现高可用可以配置多主多从集群,master将互写数据,master与slave之间传递数据。当有一master宕机,其余master和其slave依然能够正常工作。
- 如果想要操作集群,这种原生情况是有感知的。例如:我想写数据到master,读数据从slave即读写分离,就要在操作时手动切换数据库,代码层面也是。如果要想实现无感知,就需要有一个能够进行
反向代理
的工具,我们只操作一个数据库,由这个代码帮我们去使用对应的服务器。因此,集群通常需要搭配像MyCat
,ShardingSphere
这样的工具来使用。