Docker环境下MySQL与Redis集群部署实战指南
1. Docker复杂安装场景概述
当我们需要在生产环境部署数据库集群或分布式缓存系统时,Docker的优势就充分显现出来了。相比传统部署方式,容器化方案能实现环境隔离、快速扩容和统一管理。但像MySQL主从复制、Redis集群这类复杂服务的容器化部署,会遇到网络配置、数据持久化、服务发现等一系列特有的技术挑战。
我最近在金融项目中将MySQL和Redis从物理机迁移到Docker环境,期间踩了不少坑。比如Redis集群节点间通信突然中断、MySQL主从同步延迟飙升等问题,都是传统单机部署不会遇到的。通过这次实践,我总结出一套可靠的部署方案,特别适合需要高可用架构的中大型项目。
2. MySQL主从复制的容器化实现
2.1 容器网络架构设计
MySQL主从集群的容器部署,首要解决的是网络通信问题。我推荐使用自定义bridge网络,而不是默认的bridge:
docker network create --driver bridge mysql-cluster-net这种方式的优势在于:
- 容器间可以通过容器名直接通信
- 自动提供DNS解析服务
- 可以自定义子网和网关
重要提示:避免使用host网络模式,虽然简单但会带来端口冲突和安全风险。
2.2 主库容器配置
启动主库容器时需要特别注意以下参数:
docker run -d --name mysql-master \ --network mysql-cluster-net \ -v /data/mysql/master:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=yourstrongpassword \ -e MYSQL_REPLICATION_USER=repl \ -e MYSQL_REPLICATION_PASSWORD=replpass \ mysql:8.0 \ --server-id=1 \ --log-bin=mysql-bin \ --binlog-format=ROW \ --gtid-mode=ON \ --enforce-gtid-consistency=ON关键配置解析:
server-id必须是集群内唯一ID- GTID模式能确保数据一致性
- 数据卷挂载到宿主机防止数据丢失
2.3 从库容器配置
从库启动时需要连接主库:
docker run -d --name mysql-slave \ --network mysql-cluster-net \ -v /data/mysql/slave:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=yourstrongpassword \ mysql:8.0 \ --server-id=2 \ --log-slave-updates=ON \ --gtid-mode=ON \ --enforce-gtid-consistency=ON \ --skip-slave-start启动后需要在从库容器内执行:
CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='repl', MASTER_PASSWORD='replpass', MASTER_AUTO_POSITION=1; START SLAVE;2.4 常见问题排查
同步延迟问题:
- 检查主库
show processlist是否有大事务 - 调整从库
slave_parallel_workers参数 - 增加从库容器CPU和内存资源
- 检查主库
GTID不一致错误:
STOP SLAVE; SET GTID_NEXT="aaa-bbb-ccc-ddd:123"; BEGIN; COMMIT; SET GTID_NEXT="AUTOMATIC"; START SLAVE;网络中断恢复:
- 使用
docker network inspect检查网络状态 - 考虑使用
restart: always保证容器自动恢复
- 使用
3. Redis集群的容器化部署
3.1 集群规划与哈希槽分配
Redis集群采用哈希槽分区方案,共16384个槽位。我们以6节点集群为例(3主3从):
| 节点类型 | 容器名称 | 槽位范围 | 从属关系 |
|---|---|---|---|
| 主节点 | redis-node1 | 0-5460 | - |
| 主节点 | redis-node2 | 5461-10922 | - |
| 主节点 | redis-node3 | 10923-16383 | - |
| 从节点 | redis-node4 | - | node1 |
| 从节点 | redis-node5 | - | node2 |
| 从节点 | redis-node6 | - | node3 |
3.2 容器启动配置
使用官方redis镜像启动集群节点:
for port in $(seq 6379 6384); do docker run -d --name redis-node$((port-6378)) \ --net host \ -v /data/redis/node$((port-6378))/data:/data \ redis:7.0 redis-server \ --cluster-enabled yes \ --cluster-config-file nodes.conf \ --cluster-node-timeout 5000 \ --appendonly yes \ --port ${port} done注意:生产环境建议使用自定义网络而非host模式,这里为演示简化
3.3 集群初始化
进入任意容器执行集群创建命令:
redis-cli --cluster create \ 127.0.0.1:6379 \ 127.0.0.1:6380 \ 127.0.0.1:6381 \ 127.0.0.1:6382 \ 127.0.0.1:6383 \ 127.0.0.1:6384 \ --cluster-replicas 13.4 集群运维要点
节点扩容:
redis-cli --cluster add-node new_node:port existing_node:port redis-cli --cluster reshard existing_node:port故障转移测试:
- 手动停止主节点容器观察从节点晋升
- 使用
cluster nodes命令查看节点角色变化
数据迁移:
redis-cli --cluster import host:port \ --cluster-from source_host:port \ --cluster-copy
4. 生产环境优化建议
4.1 资源限制与监控
在docker-compose.yml中配置资源限制:
services: redis-node: deploy: resources: limits: cpus: '2' memory: 4G reservations: cpus: '0.5' memory: 1G推荐监控指标:
- 容器内存使用率
- Redis集群槽位覆盖状态
- MySQL主从延迟秒数
4.2 备份策略
MySQL备份方案:
docker exec mysql-master \ mysqldump -uroot -p --all-databases --single-transaction > backup.sqlRedis备份方案:
docker exec redis-node1 \ redis-cli --cluster backup /data/dump.rdb4.3 安全加固措施
- 修改默认端口
- 启用TLS加密通信
- 配置合理的ACL规则
- 定期轮换密码
5. 容器化部署的深度思考
在实际项目中,我逐渐发现容器化数据库的几个关键点:
数据持久化必须使用volume,不能依赖容器存储层。曾经因为没挂载volume导致升级时数据丢失,教训深刻。
网络时延对性能影响很大。在跨主机部署时,需要确保宿主机间的网络质量。某次故障就是因为主机间网络抖动导致Redis集群脑裂。
资源隔离不彻底可能引发问题。MySQL容器和Redis容器混部时,曾出现内存竞争导致OOM。现在会严格限制每个容器的内存上限。
监控体系需要特别设计。传统监控工具往往只监控宿主机,需要补充容器内关键指标的采集。
这些经验都是在生产环境踩坑后总结的,希望对准备容器化改造的团队有所帮助。
