使用docker-compose部署MySQL三主六从半同步集群(MMM架构)_docker-compose mysql集群
'# 使用docker-compose部署MySQL三主六从半同步集群(MMM架构)_docker-compose mysql集群
一、背景与问题
在分布式系统中,数据一致性与高可用性是核心挑战。传统MySQL主从架构虽然能满足基本需求,但在高并发、高可用场景下存在明显局限性。三主六从的半同步复制架构结合MMM(MySQL Master-Master)架构,通过以下技术特性实现高可用:
- 主主复制:每个主节点既可读写,又可作为其他主节点的从节点
- 半同步复制:通过
wsrep插件实现确认机制,确保事务在至少一个从节点确认后才提交 - 环形拓扑:三主节点形成环形复制链,六从节点按需分发
- 动态扩展:支持节点增减和故障转移
这种架构适合金融系统、大数据处理等对数据一致性要求高的场景,但不适合对延迟敏感的实时系统。
二、基本原理
1. MySQL复制机制
MySQL复制基于binlog日志实现,分为三个阶段:
# master配置
log-bin=mysql-bin
server-id=1
# slave配置
server-id=2
relay-log=mysql-relay复制流程:
- 主库将事务写入binlog
- 从库通过IO线程读取binlog
- SQL线程执行relay log
2. 半同步复制原理
通过wsrep插件实现确认机制:
# 启用半同步
SET GLOBAL wsrep_provider='libgalera.so';
SET GLOBAL wsrep_slave_threads=4;
SET GLOBAL wsrep_commit_plugin=1;关键参数:
wsrep_provider:指定插件路径wsrep_slave_threads:从节点线程数wsrep_commit_plugin:启用确认插件
3. MMM架构特性
MMM(MySQL Master-Master)架构通过以下机制实现高可用:
- 双主节点互为从节点
- 通过
wsrep插件实现一致性检查 - 支持自动故障转移
三、环境准备
1. 系统要求
- Docker 19.03+
- Docker Compose 1.25+
- Linux系统(推荐Ubuntu 20.04)
2. 安装依赖
sudo apt update
sudo apt install -y docker docker-compose3. 网络配置
创建自定义网络:
version: '3'
services:
mysql-net:
driver: bridge四、核心实现
1. docker-compose.yml结构
version: '3.8'
services:
master1:
image: mysql:8.0
container_name: mysql_master1
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_REPLICATION_USER=replica
- MYSQL_REPLICATION_PASSWORD=replica
volumes:
- ./master1:/etc/mysql/conf.d
networks:
- mysql-net
master2:
image: mysql:8.0
container_name: mysql_master2
ports:
- "3307:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_REPLICATION_USER=replica
- MYSQL_REPLICATION_PASSWORD=replica
volumes:
- ./master2:/etc/mysql/conf.d
networks:
- mysql-net
master3:
image: mysql:8.0
container_name: mysql_master3
ports:
- "3308:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_REPLICATION_USER=replica
- MYSQL_REPLICATION_PASSWORD=replica
volumes:
- ./master3:/etc/mysql/conf.d
networks:
- mysql-net
slave1:
image: mysql:8.0
container_name: mysql_slave1
ports:
- "3309:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_REPLICATION_USER=replica
- MYSQL_REPLICATION_PASSWORD=replica
volumes:
- ./slave1:/etc/mysql/conf.d
networks:
- mysql-net
slave2:
image: mysql:8.0
container_name: mysql_slave2
ports:
- "3310:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_REPLICATION_USER=replica
- MYSQL_REPLICATION_PASSWORD=replica
volumes:
- ./slave2:/etc/mysql/conf.d
networks:
- mysql-net
slave3:
image: mysql:8.0
container_name: mysql_slave3
ports:
- "3311:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_REPLICATION_USER=replica
- MYSQL_REPLICATION_PASSWORD=replica
volumes:
- ./slave3:/etc/mysql/conf.d
networks:
- mysql-net
networks:
mysql-net:
driver: bridge2. 配置文件详解
master1/my.cnf
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW
sync-binlog=1
innodb_flush_log_at_trx_commit=1
wsrep_provider=/usr/lib64/galera22/libgalera_smm.so
wsrep_slave_threads=4
wsrep_commit_plugin=1
wsrep_sst_method=mysqldump
wsrep_node_name=master1
wsrep_node_address=172.18.0.2slave1/my.cnf
[mysqld]
server-id=10
log-bin=mysql-bin
binlog-format=ROW
sync-binlog=1
innodb_flush_log_at_trx_commit=1
relay-log=mysql-relay
relay-log-index=mysql-relay.index3. 初始化集群
# 启动第一个主节点
docker-compose up -d mysql_master1
# 初始化第一个主节点
docker exec -i mysql_master1 mysqld --initialize
# 创建复制用户
docker exec -i mysql_master1 mysql -u root -p --execute="CREATE USER 'replica'@'%' IDENTIFIED BY 'replica'; GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%' IDENTIFIED BY 'replica'; FLUSH PRIVILEGES;"
# 启动其他节点
docker-compose up -d mysql_master2 mysql_master3 mysql_slave1 mysql_slave2 mysql_slave3五、完整案例
1. 集群拓扑
Master1 (172.18.0.2) -> Slave1 (172.18.0.3)
↓
Master2 (172.18.0.4) -> Slave2 (172.18.0.5)
↓
Master3 (172.18.0.6) -> Slave3 (172.18.0.7)2. 配置文件完整示例
master1/my.cnf
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW
sync-binlog=1
innodb_flush_log_at_trx_commit=1
wsrep_provider=/usr/lib64/galera22/libgalera_smm.so
wsrep_slave_threads=4
wsrep_commit_plugin=1
wsrep_sst_method=mysqldump
wsrep_node_name=master1
wsrep_node_address=172.18.0.2
wsrep_cluster_address="gcomm://172.18.0.2,172.18.0.4,172.18.0.6"slave1/my.cnf
[mysqld]
server-id=10
log-bin=mysql-bin
binlog-format=ROW
sync-binlog=1
innodb_flush_log_at_trx_commit=1
relay-log=mysql-relay
relay-log-index=mysql-relay.index3. 启动集群
docker-compose up -d六、源码解析
1. Galera插件原理
Galera插件通过wsrep接口实现:
wsrep_sst_method:指定同步方式(mysqldump、xtrabackup)wsrep_node_name:节点名称wsrep_node_address:节点IPwsrep_cluster_address:集群地址列表
2. 半同步确认机制
# 查询半同步状态
SHOW STATUS LIKE 'wsrep%';关键参数:
wsrep_flow_control_mode:流量控制模式wsrep_commit_count:确认事务数wsrep_certification_wait_timeout:超时时间
七、进阶使用
1. 动态扩展
添加新从节点:
new_slave:
image: mysql:8.0
container_name: mysql_new_slave
ports:
- "3312:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_REPLICATION_USER=replica
- MYSQL_REPLICATION_PASSWORD=replica
volumes:
- ./new_slave:/etc/mysql/conf.d
networks:
- mysql-net2. 故障转移
# 检查集群状态
docker exec -i mysql_master1 mysql -u root -p --execute="SHOW STATUS LIKE 'wsrep%';"
# 手动切换主从
docker exec -i mysql_master1 mysql -u root -p --execute="STOP SLAVE; RESET SLAVE; CHANGE MASTER TO MASTER_HOST='172.18.0.4'; START SLAVE;"八、性能与工程实践
1. 性能优化
调整缓冲池大小:
innodb_buffer_pool_size=2G启用压缩传输:
wsrep_slave_threads=8使用SSD存储:
volumes: - /mnt/ssd/mysql:/var/lib/mysql
2. 安全风险
- 配置文件暴露敏感信息
- 网络暴露给外部
- 未启用SSL加密
解决方案:
# 启用SSL
require_secure_transport=1九、常见问题与踩坑
1. 常见错误
错误1:复制延迟
SHOW SLAVE STATUS\G解决方法:检查网络带宽,调整wsrep_slave_threads
错误2:主主冲突
SHOW ENGINE INNODB STATUS\G解决方法:检查wsrep_sst_method配置
错误3:节点无法加入集群
docker logs mysql_master1解决方法:检查wsrep_cluster_address配置
2. 常见坑
- 忽略
server-id冲突 - 未设置
binlog_format=ROW - 忘记配置
wsrep_sst_method
十、最佳实践
配置建议:
- 使用
ROW格式binlog - 设置
innodb_buffer_pool_size=2G - 启用SSL加密
- 使用
运维建议:
- 定期检查
SHOW STATUS LIKE 'wsrep%'; - 使用Prometheus监控集群状态
- 每周进行一次数据一致性校验
- 定期检查
安全建议:
- 使用Vault管理敏感信息
- 配置防火墙限制访问
- 启用SSL和认证
十一、总结
本文深入解析了基于docker-compose的MySQL三主六从半同步集群部署方案。通过Galera插件实现的半同步复制机制,结合MMM架构的主主复制特性,构建了一个高可用、高可靠的数据集群。这种架构适用于对数据一致性要求极高的场景,但需要权衡其对延迟的影响。
在实际应用中,建议:
- 对于金融系统、大数据处理等场景使用
- 避免在实时交易系统中使用
- 定期进行故障转移演练
- 监控关键指标(如延迟、确认数)
通过合理配置和优化,可以构建一个稳定可靠的MySQL集群,满足复杂业务需求。
评论已关闭