使用docker-compose部署MySQL三主六从半同步集群(MMM架构)_docker-compose mysql集群

'# 使用docker-compose部署MySQL三主六从半同步集群(MMM架构)_docker-compose mysql集群

一、背景与问题

在分布式系统中,数据一致性与高可用性是核心挑战。传统MySQL主从架构虽然能满足基本需求,但在高并发、高可用场景下存在明显局限性。三主六从的半同步复制架构结合MMM(MySQL Master-Master)架构,通过以下技术特性实现高可用:

  1. 主主复制:每个主节点既可读写,又可作为其他主节点的从节点
  2. 半同步复制:通过wsrep插件实现确认机制,确保事务在至少一个从节点确认后才提交
  3. 环形拓扑:三主节点形成环形复制链,六从节点按需分发
  4. 动态扩展:支持节点增减和故障转移

这种架构适合金融系统、大数据处理等对数据一致性要求高的场景,但不适合对延迟敏感的实时系统。

二、基本原理

1. MySQL复制机制

MySQL复制基于binlog日志实现,分为三个阶段:

# master配置
log-bin=mysql-bin
server-id=1

# slave配置
server-id=2
relay-log=mysql-relay

复制流程:

  1. 主库将事务写入binlog
  2. 从库通过IO线程读取binlog
  3. 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-compose

3. 网络配置

创建自定义网络:

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: bridge

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

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.index

3. 初始化集群

# 启动第一个主节点
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.index

3. 启动集群

docker-compose up -d

六、源码解析

1. Galera插件原理

Galera插件通过wsrep接口实现:

  • wsrep_sst_method:指定同步方式(mysqldump、xtrabackup)
  • wsrep_node_name:节点名称
  • wsrep_node_address:节点IP
  • wsrep_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-net

2. 故障转移

# 检查集群状态
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

十、最佳实践

  1. 配置建议:

    • 使用ROW格式binlog
    • 设置innodb_buffer_pool_size=2G
    • 启用SSL加密
  2. 运维建议:

    • 定期检查SHOW STATUS LIKE 'wsrep%';
    • 使用Prometheus监控集群状态
    • 每周进行一次数据一致性校验
  3. 安全建议:

    • 使用Vault管理敏感信息
    • 配置防火墙限制访问
    • 启用SSL和认证

十一、总结

本文深入解析了基于docker-compose的MySQL三主六从半同步集群部署方案。通过Galera插件实现的半同步复制机制,结合MMM架构的主主复制特性,构建了一个高可用、高可靠的数据集群。这种架构适用于对数据一致性要求极高的场景,但需要权衡其对延迟的影响。

在实际应用中,建议:

  • 对于金融系统、大数据处理等场景使用
  • 避免在实时交易系统中使用
  • 定期进行故障转移演练
  • 监控关键指标(如延迟、确认数)

通过合理配置和优化,可以构建一个稳定可靠的MySQL集群,满足复杂业务需求。

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日