可行,但需满足三点:host网络或正确端口映射(6379+16379)、唯一持久化的cluster-config-file、所有节点启动后自动执行redis-cli --cluster create初始化,否则仅为6个孤立实例。

直接上结论:用 docker-compose.yml 一键部署三主三从 Redis 集群是可行的,但“一键”不等于“无脑”,关键在三点——host 网络模式或自定义 bridge + 正确端口映射、cluster-config-file 必须唯一且可持久化、所有节点启动后必须自动完成 redis-cli --cluster create 或等效初始化。否则容器起来只是 6 个孤立 Redis 实例,不是集群。
为什么 docker-compose 默认 bridge 网络会导致集群握手失败
Redis Cluster 节点间依赖两个端口通信:6379(客户端端口)和 16379(cluster bus 端口,固定为 client port + 10000)。Docker 默认 bridge 网络下,容器内看到的 IP 是内网地址(如 172.20.0.2),而 cluster-node-timeout 机制要求节点能互相通过「对外暴露的 IP:port」发现彼此。若只映射 6379,16379 不暴露,Gossip 协议就收不到心跳,节点状态卡在 connecting 或直接超时下线。
- 阿里云/腾讯云 ECS 上必须开放安全组规则:允许入方向
6379和16379端口(对所有集群节点 IP) - 本地测试可用
network_mode: "host"绕过映射问题,但仅限单机,且会占用宿主机端口 - 更稳妥的做法是显式声明
ports并确保redis.conf中cluster-announce-ip设为宿主机真实 IP(非0.0.0.0或127.0.0.1)
redis.conf 里哪些配置项不能共用同一份文件
6 个节点若共用一个 redis.conf 模板但没做差异化处理,nodes-*.conf 写入冲突、槽位分配错乱、甚至启动失败。核心冲突点在:
-
port:每个服务必须不同,如7000~7005 -
cluster-config-file:必须与端口一一对应,如nodes-7000.conf、nodes-7001.conf,否则多个进程写同一个文件会损坏集群元数据 -
cluster-announce-ip:必须填宿主机可被其他节点访问的真实 IP,不能写localhost或容器内部 DNS 名 -
appendfilename和dbfilename:建议按端口区分,避免 AOF/RDB 文件混用
推荐做法:用 env_file 或 command 动态注入变量,或用 sed 在启动前生成独立配置文件。
如何避免手动执行 redis-cli --cluster create
所谓“一键”,是指容器启动后自动完成集群创建,而不是靠人敲命令。常见可靠做法有两种:
- 用初始化脚本:在
command中写 shell 命令链,先启动 Redis(--port 7000 --cluster-enabled yes ...),再用sleep等待所有容器就绪(约 5–10 秒),最后调用redis-cli --cluster create指定全部 6 个IP:PORT,加--cluster-replicas 1自动分配从节点 - 用健康检查+外部工具:比如用 Python 脚本轮询所有节点
redis-cli -p 7000 ping返回PONG后再触发创建,适合复杂编排场景 - 注意:如果用了密码,必须在
--cluster create命令中加-a,否则认证失败报(error) NOAUTH Authentication required
别信“只要配了 cluster-enabled yes 就自动成集群”的说法——Redis 不会自己找邻居,它只负责响应 meet 消息,发起者得是你。
最易被忽略的故障点:节点重启后 cluster-config-file 权限与残留
每次集群初始化成功后,Redis 会在 cluster-config-file 所在目录生成二进制文件(如 nodes-7000.conf),里面存着 node id、role、slots 分配等关键信息。这个文件一旦被清空、覆盖或 chmod 错误(比如挂载卷权限是 root,而容器内 redis 用户是 redis),节点重启就会以全新身份加入,导致整个集群 slot 映射混乱、数据不可读。
务必确认:/data 挂载目录对 redis 用户可读写;nodes-*.conf 文件在首次创建后不要手动编辑;升级镜像前先备份这些文件。











