当前位置: 首页 > news >正文

Docker 环境下 MySQL 主从复制集群、MGR 搭建及 Nginx 反向代理配置

在现代的软件开发和运维中,容器化技术如 Docker 极大地简化了应用程序的部署和管理。本文将详细介绍如何使用 Docker 搭建 MySQL 主从复制集群、MySQL Group Replication (MGR) 集群,以及配置 Nginx 反向代理,同时提供相应的配置步骤和测试方法。

一、MySQL 主从复制集群搭建

1. 架构图

MySQL 主从复制集群由一个主节点(Master)和两个从节点(Slave)组成,架构图如下:

plaintext

+-------------------+                          +--------------------+                          +--------------------+
|                   |                          |                    |                          |                    |
|   MySQL Master    |--------------------------|   MySQL Slave 1    |--------------------------|   MySQL Slave 2    |
|  IP: 172.18.0.10  |                          | IP: 172.18.0.11    |                          | IP: 172.18.0.12    |
|  Port: 3306       |                          | Port: 3306         |                          | Port: 3306         |
|  Data Dir: /data/mysql/master        |  Data Dir: /data/mysql/slave1       			|  Data Dir: /data/mysql/slave2        |
+-------------------+                          +--------------------+                          +--------------------+

2. 配置文件复制

首先启动一个临时 MySQL 容器来提取默认配置文件:

​​docker run -d --name mysql-temp mysql:8.0

等待几秒后,将配置文件复制到本地:

mkdir -p /data/mysql/conf
docker cp mysql-temp:/etc/my.cnf /data/mysql/conf/my.cnf

停止并删除临时容器:

docker stop mysql-temp && docker rm mysql-temp

创建主从节点的目录结构并复制配置文件:

mkdir -p /data/mysql/{master,slave1,slave2}/{conf,data}
cp /data/mysql/conf/my.cnf /data/mysql/master/conf/
cp /data/mysql/conf/my.cnf  /data/mysql/slave1/conf/
cp /data/mysql/conf/my.cnf  /data/mysql/slave2/conf/

3. 网络搭建

使用自定义网络和静态 IP 地址可以更好地规划和管理网络:

docker network create \--driver bridge \--subnet=172.18.0.0/24 \custom-mysql-network

启动 Master 容器并指定固定 IP:

docker run -d \--name mysql-master \--network custom-mysql-network \--ip 172.18.0.10 \-e MYSQL_ROOT_PASSWORD=root \mysql:8.0

4. 修改配置文件

分别修改主从节点的配置文件:

  • Master 配置文件 /data/mysql/master/conf/my.cnf
    [mysqld]
    server-id=1
    log-bin=binlog
    binlog-format=row

  • Slave 1 配置文件 /data/mysql/slave1/conf/my.cnf
    [mysqld]
    server-id=2
    relay-log=relaylog
    log-slave-updates=1

    Slave 2 配置文件 /data/mysql/slave2/conf/my.cnf

    [mysqld]
    server-id=3
    relay-log=relaylog
    log-slave-updates=1

    5. 启动 MySQL 容器

    启动主从节点的 MySQL 容器:

    # 启动 Master
    docker run -d \--name mysql-master \--network custom-mysql-network \--ip 172.18.0.10 \--mount type=bind,source=/data/mysql/master/conf/my.cnf,target=/etc/my.cnf \--mount type=bind,source=/data/mysql/master/data,target=/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=root \mysql:8.0# 启动 Slave 1
    docker run -d \--name mysql-slave1 \--network custom-mysql-network \--ip 172.18.0.11 \--mount type=bind,source=/data/mysql/slave1/conf/my.cnf,target=/etc/my.cnf \--mount type=bind,source=/data/mysql/slave1/data,target=/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=root \mysql:8.0# 启动 Slave 2
    docker run -d \--name mysql-slave2 \--network custom-mysql-network \--ip 172.18.0.12 \--mount type=bind,source=/data/mysql/slave2/conf/my.cnf,target=/etc/my.cnf \--mount type=bind,source=/data/mysql/slave2/data,target=/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=root \mysql:8.0

    6. 创建复制账户

    进入 Master 容器创建用于复制的用户并查看 Binlog 状态:

    # 创建复制用户
    docker exec -it mysql-master mysql -uroot -proot -e "
    CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
    FLUSH PRIVILEGES;
    "# 查看当前 Binlog 状态
    docker exec -it mysql-master mysql -uroot -proot -e "SHOW MASTER STATUS;"

    7. 配置主从关系

    分别配置 Slave 1 和 Slave 2 的主从关系并查看状态:

    # 配置 Slave 1
    docker exec -it mysql-slave1 mysql -uroot -proot -e "
    CHANGE MASTER TOMASTER_HOST='172.18.0.10',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=2553;
    START SLAVE;
    "
    docker exec -it mysql-slave1 mysql -uroot -proot -e "SHOW SLAVE STATUS\G"# 配置 Slave 2
    docker exec -it mysql-slave2 mysql -uroot -proot -e "
    CHANGE MASTER TOMASTER_HOST='172.18.0.10',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=2553;
    START SLAVE;
    "
    docker exec -it mysql-slave2 mysql -uroot -proot -e "SHOW SLAVE STATUS\G"

    8. 测试主从同步

    在 Master 上插入测试数据,然后在 Slave 1 和 Slave 2 上查询数据:

    # 在 Master 上插入数据
    docker exec -it mysql-master mysql -uroot -proot -e "
    CREATE DATABASE testdb;
    USE testdb;
    CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50));
    INSERT INTO users (name) VALUES ('Alice'), ('Bob');
    "# 在 Slave 1 和 Slave 2 上查询数据
    docker exec -it mysql-slave1 mysql -uroot -proot -e "SELECT * FROM testdb.users;"
    docker exec -it mysql-slave2 mysql -uroot -proot -e "SELECT * FROM testdb.users;"

    二、MGR 搭建

    1. 使用 GTID 主从

    修改所有节点的 my.cnf 配置文件,启用 GTID 模式:

    # Master 配置
    [mysqld]
    server-id=1
    log-bin=mysql-bin
    gtid_mode=ON
    enforce-gtid-consistency=ON# Slave 1 配置
    [mysqld]
    server-id=2
    relay-log=mysql-relay-bin
    gtid_mode=ON
    enforce-gtid-consistency=ON# Slave 2 配置
    [mysqld]
    server-id=3
    relay-log=mysql-relay-bin
    gtid_mode=ON
    enforce-gtid-consistency=ON

    重启所有 MySQL 容器:

    docker restart mysql-master
    docker restart mysql-slave1
    docker restart mysql-slave2

    设置主库连接信息并验证 GTID 主从状态:

    # 在 Slave 1 上执行
    docker exec -it mysql-slave1 mysql -uroot -proot -e "STOP SLAVE;"
    docker exec -it mysql-slave1 mysql -uroot -proot -e "
    CHANGE MASTER TOMASTER_HOST='172.18.0.10',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_AUTO_POSITION=1;
    "
    docker exec -it mysql-slave1 mysql -uroot -proot -e "START SLAVE;"# 在 Slave 2 上执行
    docker exec -it mysql-slave2 mysql -uroot -proot -e "STOP SLAVE;"
    docker exec -it mysql-slave2 mysql -uroot -proot -e "
    CHANGE MASTER TOMASTER_HOST='172.18.0.10',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_AUTO_POSITION=1;
    "
    docker exec -it mysql-slave2 mysql -uroot -proot -e "START SLAVE;"# 验证 GTID 主从状态
    docker exec -it mysql-slave1 mysql -uroot -proot -e "SHOW SLAVE STATUS\G"
    docker exec -it mysql-slave2 mysql -uroot -proot -e "SHOW SLAVE STATUS\G"

    2. 修改配置文件

    分别修改 Master、Slave 1 和 Slave 2 的配置文件:

    # Master 节点配置
    [mysqld]
    server_id=1
    gtid_mode=ON
    enforce_gtid_consistency=ONplugin_dir=/usr/lib64/mysql/plugin
    binlog_checksum=NONEtransaction_write_set_extraction=XXHASH64
    loose-group_replication_recovery_use_ssl=ON
    loose-group_replication_group_name="aaaaaaaa-aaaa-4aaa-aacd-1234567890ab"
    loose-group_replication_start_on_boot=OFFloose-group_replication_local_address="master:24901"
    loose-group_replication_group_seeds="master:24901,slave1:24901,slave2:24901"loose-group_replication_bootstrap_group=OFF# Slave1 节点配置
    [mysqld]
    server_id=2
    gtid_mode=ON
    enforce_gtid_consistency=ONplugin_dir=/usr/lib64/mysql/plugin
    binlog_checksum=NONEloose-group_replication_recovery_get_public_key=ON
    loose-group_replication_recovery_use_ssl=OFF
    loose-group_replication_group_name="aaaaaaaa-aaaa-4aaa-aacd-1234567890ab"
    loose-group_replication_start_on_boot=OFFloose-group_replication_local_address= "slave1:24901"
    loose-group_replication_group_seeds= "master:24901,slave1:24901,slave2:24901"loose-group_replication_bootstrap_group=OFF# Slave2 节点配置
    [mysqld]
    server_id=3
    gtid_mode=ON
    enforce_gtid_consistency=ONplugin_dir=/usr/lib64/mysql/plugin
    binlog_checksum=NONEloose-group_replication_recovery_get_public_key=ON
    loose-group_replication_recovery_use_ssl=OFF
    loose-group_replication_group_name="aaaaaaaa-aaaa-4aaa-aacd-1234567890ab"
    loose-group_replication_start_on_boot=OFFloose-group_replication_local_address= "slave2:24901"
    loose-group_replication_group_seeds= "master:24901,slave1:24901,slave2:24901"loose-group_replication_bootstrap_group=OFF

    3. 启动容器

    docker restart master
    docker restart slave1
    docker restart slave2

    4. 初始化 MGR 集群

    进入 Master 容器进行初始化操作:

    docker exec -it master mysql -uroot -proot
    -- 清除旧主从信息
    STOP SLAVE;
    RESET SLAVE ALL;
    RESET MASTER;-- 创建复制用户和权限
    CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
    FLUSH PRIVILEGES;-- 安装 MGR 插件
    INSTALL PLUGIN group_replication SONAME 'group_replication.so';-- 引导第一个节点加入组
    SET GLOBAL group_replication_bootstrap_group=ON;
    START GROUP_REPLICATION;
    SET GLOBAL group_replication_bootstrap_group=OFF;

    分别进入 Slave 1 和 Slave 2 容器添加节点:

    docker exec -it slave1 mysql -uroot -proot
    -- 清除旧数据
    STOP SLAVE;
    RESET SLAVE ALL;
    RESET MASTER;-- 安装插件
    INSTALL PLUGIN group_replication SONAME 'group_replication.so';-- 设置同步账户
    CHANGE MASTER TOMASTER_USER='slave',MASTER_PASSWORD='123456'FOR CHANNEL 'group_replication_recovery';-- 启动组复制
    START GROUP_REPLICATION;

    验证集群状态

    SELECT * FROM performance_schema.replication_group_members;

    三、Nginx 反向代理配置

    1. 部署 Nginx 前端项目

    docker run -itd --name n1 \
    -v /data/nginx/html:/etc/nginx/html \
    -p 80:80 \
    nginx

    2. 挂载对应配置文件

    复制并修改配置文件:

    server {listen  80;server_name  localhost;location / {root   /etc/nginx/html/;index  index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   /usr/share/nginx/html;}}

    重新启动 Nginx 容器:

    docker run -itd --name n1 \
    -v /data/nginx/html:/etc/nginx/html \
    -v /data/nginx/conf.d:/etc/nginx/conf.d \
    -p 80:80 \
    nginx

    3. 部署后端服务

    docker pull openjdk:8
    docker network create my-networkdocker run -d \--name s1 \--network my-network \-v /data/java:/java \openjdk:8 \tail -f /dev/nulldocker run -d \--name s2 \--network my-network \-v /data/java:/java \openjdk:8 \tail -f /dev/nulldocker run -d \--name s3 \--network my-network \-v /data/java:/java \openjdk:8 \tail -f /dev/nulldocker exec s1 java -jar /java/msg.jar
    docker exec s2 java -jar /java/msg.jar
    docker exec s3 java -jar /java/msg.jar

    4. 搭建反向代理

    docker network connect my-network n1
    # 服务器的集群
    upstream tomcatList { server s1:8081 weight=1; server s2:8081 weight=1; server s3:8081 weight=1;  
    } location ~^/api/ {rewrite ^/api/(.*)$ /$1 break;proxy_pass  http://tomcatList;proxy_redirect default;
    }

    通过以上步骤,我们成功搭建了 MySQL 主从复制集群、MGR 集群,并配置了 Nginx 反向代理。这些技术的应用可以提高系统的可用性、性能和可扩展性。

http://www.dtcms.com/a/271792.html

相关文章:

  • SSRF10 各种限制绕过之30x跳转绕过协议限制
  • ip地址可以精确到什么级别?如何获取/更改ip地址
  • 配置双网卡Linux主机作为路由器(连接NAT网络和仅主机模式网络)
  • 在 Mac 上使用 Git 拉取项目:完整指南
  • 【算法笔记】6.LeetCode-Hot100-链表专项
  • selenium中find_element()用法进行元素定位
  • 在mac m1基于llama.cpp运行deepseek
  • Spring Boot 企业级动态权限全栈深度解决方案,设计思路,代码分析
  • C#基础:Winform桌面开发中窗体之间的数据传递
  • 【WEB】Polar靶场 Day8 详细笔记
  • 力扣 hot100 Day40
  • fastMCP基础(一)
  • imx6ull-裸机学习实验16——I2C 实验
  • 解锁localtime:使用技巧与避坑指南
  • shell 字符串常用操作
  • 网安系列【16】之Weblogic和jboss漏洞
  • 深入剖析 ADL:C++ 中的依赖查找机制及其编译错误案例分析
  • 短剧分销系统开发指南:从0到1构建高效变现平台
  • 基于双向cuk斩波均衡电路的串联锂离子均衡系统设计
  • 文心一言4.5开源部署指南及文学领域测评
  • frp内网穿透下创建FTP(解决FTP“服务器回应不可路由的地址。使用服务器地址替代”错误)
  • 【macos用镜像站体验】Claude Code入门使用教程和常用命令
  • JS实现页面实时时间显示/倒计时
  • SMTPman,smtp的端口号是多少全面解析配置
  • 【数据结构】时间复杂度和空间复杂度
  • 杰赛S65_中星微ZX296716免拆刷机教程解决网络错误和时钟问题
  • Java线程池原理概述
  • 浏览器 实时监听音量 实时语音识别 vue js
  • 解析LLM层裁剪:Qwen实战指南
  • 搭建自动化工作流:探寻解放双手的有效方案(1)