Docker-compose实战:MySQL主从集群的自动化部署与网络配置
1. 为什么需要MySQL主从集群作为开发者我们经常会遇到数据库性能瓶颈的问题。想象一下当你的应用用户量突然激增所有查询请求都压在一台数据库服务器上那场景就像节假日的高速公路收费站——所有车辆挤在唯一开放的通道排队等待的时间越来越长。这时候MySQL主从集群就像是同时开放了多个收费通道能够有效分流压力。我在实际项目中遇到过多次类似情况。有一次一个电商平台的促销活动导致数据库查询响应时间从200ms飙升到5秒以上用户体验直线下降。后来通过部署主从集群将读操作分散到多个从库问题立刻得到缓解。主从集群的核心价值在于读写分离主库Master负责处理写操作INSERT/UPDATE/DELETE从库Slave处理读操作SELECT。根据统计大多数业务场景中读操作占比高达70%-80%数据备份从库实时同步主库数据相当于多了一份热备份。去年我们有个主库硬盘突然损坏就是靠从库快速恢复业务负载均衡通过轮询或权重方式将查询请求分发到不同从库高可用性主库宕机时可以快速提升某个从库为主库需要配合额外工具如MHA传统部署主从集群需要分别在多台服务器安装配置MySQL过程繁琐。而使用Docker-compose我们可以用一份配置文件在单台机器上快速搭建完整的主从环境特别适合开发测试和中小型项目。2. 环境准备与Docker网络配置2.1 基础环境检查在开始之前确保你的系统已经安装以下组件# 检查Docker版本建议18.06 docker --version # 检查docker-compose版本建议1.25 docker-compose --version如果尚未安装可以参考官方文档进行安装。我推荐使用Linux系统如Ubuntu 20.04作为宿主机Windows和Mac虽然也能运行但性能会有损耗。2.2 创建专用Docker网络Docker网络是容器间通信的关键。在我们的方案中所有数据库容器都需要加入同一个自定义网络。这样做的好处是容器间可以通过容器名直接访问不需要记IP地址与宿主机和其他容器网络隔离更安全可以自定义子网范围避免IP冲突创建网络的命令很简单docker network create --subnet172.16.0.0/24 basenetwork这里我特意选择了172.16.0.0/24这个不常用的私有网段避免与公司内网冲突。你可以根据实际情况调整。创建后可以用以下命令验证docker network inspect basenetwork在我的实践中建议将所有基础服务MySQL、Redis等都放在这个网络里方便互相调用。曾经有个项目因为网络配置不当导致应用容器连不上数据库排查了半天才发现是网络隔离问题。3. Docker-compose文件深度解析3.1 项目目录结构设计清晰的目录结构能让后期维护轻松很多。这是我推荐的结构mysql-cluster/ ├── docker-compose.yml ├── init_db/ # 初始化SQL脚本 ├── master/ │ ├── data/ # 主库数据持久化目录 │ └── my.cnf # 主库配置文件 └── slave/ ├── data/ # 从库数据持久化目录 └── my.cnf # 从库配置文件这种结构的好处是配置文件与数据分离方便备份每个实例有独立目录避免混淆符合Docker最佳实践3.2 完整的docker-compose.yml下面是我优化过的docker-compose文件增加了注释说明关键参数version: 3.7 services: mysql-master: container_name: mysql-master image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: master_root_password MYSQL_REPLICATION_USER: repl_user MYSQL_REPLICATION_PASSWORD: repl_password volumes: - ./master/data:/var/lib/mysql - ./master/my.cnf:/etc/mysql/my.cnf - ./init_db:/docker-entrypoint-initdb.d ports: - 3306:3306 networks: basenetwork: ipv4_address: 172.16.0.101 mysql-slave-1: container_name: mysql-slave-1 image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: slave_root_password volumes: - ./slave-1/data:/var/lib/mysql - ./slave-1/my.cnf:/etc/mysql/my.cnf networks: basenetwork: ipv4_address: 172.16.0.102 depends_on: - mysql-master networks: basenetwork: external: true几个关键点说明使用MySQL 5.7镜像是因为它稳定且兼容性好新项目可以考虑8.0通过volumes实现数据持久化即使容器重启数据也不会丢失为每个容器分配固定IP方便后续连接depends_on确保从库在主库启动后再启动3.3 配置文件详解主库的my.cnf需要特别配置以下参数[mysqld] server-id 1 log-bin mysql-bin binlog_format ROW expire_logs_days 7 binlog_do_db your_database_name从库配置有所不同[mysqld] server-id 2 # 必须与主库不同 relay-log mysql-relay-bin read_only 1 # 从库只读这些配置确保了主库生成二进制日志(binlog)供从库同步每个实例有唯一server-id从库设置为只读模式防止误操作4. 主从同步配置实战4.1 启动集群在项目目录下执行docker-compose up -d这个命令会启动所有定义的服务。建议先用docker-compose config检查配置是否正确。启动后可以用以下命令查看状态docker-compose ps如果看到所有容器状态都是Up说明启动成功。我第一次尝试时因为目录权限问题导致MySQL启动失败后来发现需要确保data目录对Docker进程可写。4.2 配置主从关系在主库容器中执行docker exec -it mysql-master mysql -uroot -p登录后创建复制账号并授权CREATE USER repl_user% IDENTIFIED BY repl_password; GRANT REPLICATION SLAVE ON *.* TO repl_user%; FLUSH PRIVILEGES;记录下主库状态SHOW MASTER STATUS;你会看到类似这样的输出------------------------------------------------------------ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | ------------------------------------------------------------ | mysql-bin.000003 | 745 | | | ------------------------------------------------------------然后在从库容器中配置主库信息CHANGE MASTER TO MASTER_HOSTmysql-master, MASTER_USERrepl_user, MASTER_PASSWORDrepl_password, MASTER_LOG_FILEmysql-bin.000003, -- 上面查到的文件名 MASTER_LOG_POS745; -- 上面查到的位置 START SLAVE;4.3 验证同步状态在从库执行SHOW SLAVE STATUS\G重点关注以下字段Slave_IO_Running: YesSlave_SQL_Running: YesSeconds_Behind_Master: 0如果看到错误常见原因包括网络不通检查容器间能否ping通复制账号权限不足server-id配置重复主库binlog位置不正确5. 高级配置与故障排查5.1 GTID模式配置对于生产环境我推荐启用GTID全局事务标识符模式可以简化故障恢复。在主从配置文件中添加gtid_modeON enforce_gtid_consistencyON然后从库的CHANGE MASTER命令可以简化为CHANGE MASTER TO MASTER_HOSTmysql-master, MASTER_USERrepl_user, MASTER_PASSWORDrepl_password, MASTER_AUTO_POSITION1;5.2 常见问题解决问题1从库同步延迟大解决方案检查主库负载考虑增加从库数量或升级配置监控命令SHOW SLAVE STATUS中的Seconds_Behind_Master问题2主从数据不一致解决方案使用pt-table-checksum工具检查差异修复命令pt-table-sync --replicatept.checksums hmaster,uroot,ppassword --sync-to-master问题3从库复制中断常见错误1062主键冲突、1032记录不存在临时跳过SET GLOBAL sql_slave_skip_counter1; START SLAVE;长期方案分析业务逻辑避免在从库写入5.3 性能优化建议binlog格式对于UPDATE多的场景用ROWSELECT多的用STATEMENT缓存设置适当增加binlog_cache_size和max_binlog_size网络优化如果跨机房同步考虑压缩binlogbinlog_row_imageMINIMAL监控告警配置PrometheusGranfa监控复制延迟6. 实际应用场景6.1 读写分离实现在应用中可以通过以下方式实现读写分离// Spring Boot配置示例 Configuration public class DataSourceConfig { Bean Primary public DataSource masterDataSource() { // 配置主库数据源 } Bean public DataSource slaveDataSource() { // 配置从库数据源 } Bean public AbstractRoutingDataSource routingDataSource() { // 实现读写分离路由 } }6.2 数据备份策略利用从库做备份不会影响主库性能# 在从库服务器执行 docker exec mysql-slave-1 mysqldump -uroot -p dbname backup.sql建议配合crontab设置定时备份并上传到云存储。6.3 扩展多个从库只需在docker-compose.yml中添加新服务mysql-slave-2: container_name: mysql-slave-2 image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: slave_root_password volumes: - ./slave-2/data:/var/lib/mysql - ./slave-2/my.cnf:/etc/mysql/my.cnf networks: basenetwork: ipv4_address: 172.16.0.103 depends_on: - mysql-master然后按照相同步骤配置主从关系即可。我曾经为一个数据分析平台配置了5个从库分别用于不同的报表查询。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2523658.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!