1. 决定用 Docker 搭建 Redis 集群前我先想清楚了这几件事先说结论用 Docker 搭 Redis 集群完全可行但如果你直接按单机版思路去跑大概率会在网络这关上翻车。我自己就是从“docker run 一个 redis 然后 cluster meet”起步的结果卡了整整一个下午。这篇文章就把我完整的实操过程、踩坑记录和最终可用的方案整理出来希望你能少走几步弯路。先说我的实际需求。公司内部有个数据看板项目平时读多写少但单机 Redis 的瓶颈已经很明显了——高峰期连接数打到上限偶尔还会出现 key 过期淘汰导致的延迟抖动。我想在测试环境搭一套真实的 Redis Cluster先把故障转移、槽位重分配这些机制摸透再考虑迁移到生产。考虑到手头就一台 16G 内存的服务器直接跑三个虚拟机有点浪费Docker 容器是最轻量的选择。但在动手之前有几个关键点必须掰清楚。第一Docker 容器里的 Redis 集群和物理机部署有什么区别物理机部署时每个 Redis 实例直接用宿主机 IP 和固定端口通信。而 Docker 容器的 IP 是动态的重启后会变化而且默认网络模式下容器之间的通信要依赖端口映射或自定义网络。Redis Cluster 的节点之间需要通过 gossip 协议互相发现和交换状态如果容器 IP 变化整个集群的节点信息就乱了。第二Redis 集群的节点发现机制决定了端口必须“内外一致”。Redis Cluster 的每个节点会向其他节点通告自己的 IP 和端口。如果容器内 Redis 监听的端口和映射到宿主机上的端口不一致集群在握手时会拿不到正确的节点信息。比如你在容器内让 Redis 监听 7001但映射到宿主机是 17001那么其他节点收到的是“172.17.0.x:7001”这个地址在集群外根本访问不通。第三广播地址cluster-announce-ip是 Docker 部署的生命线。好在 Redis 从 3.2.0 版本开始提供了cluster-announce-ip、cluster-announce-port、cluster-announce-bus-port三个配置项专门用来处理 NAT 环境或 Docker 端口映射的场景。这套配置告诉集群“虽然我在容器里但请用我指定的 IP 和端口来访问我”。这也是我能继续往下推进的关键。所以如果你也想在 Docker 下搭 Redis 集群第一步不是急着写 docker-compose而是把网络模型想清楚你是准备让容器直接用宿主机网络模式--network host还是用自定义 bridge 网络 固定 IP或者用端口映射 announce 配置。三种方案我都试过下面会逐个说结论。2. 方案选型三种网络模式我都试了一遍在做任何部署之前我觉得最值得对比的就是怎么让容器网络和 Redis Cluster 的通信模型匹配。这个选择决定了后面所有步骤的复杂度也决定了集群的稳定性。2.1 方案一host 网络模式最简单但最容易出问题docker run --network host的意思是容器直接用宿主机的网络栈。这样容器的 Redis 监听端口就是宿主机端口Redis 集群节点间通信用的也是宿主机 IP完全回到“物理机部署”的逻辑配置最少。听起来很美好但问题在于一个宿主机端口只能被一个容器占用。也就是说如果你在三台宿主机上各部署两个 Redis 节点那没问题。但如果在一台机器上部署六个容器节点host 模式下端口冲突直接让你连启动都做不到。你可以让不同容器监听不同端口来解决比如 7001-7006但这样你就退回到“手动管理端口”的模式docker 的资源隔离优势大打折扣。还有一个实际运营上的坑团队里如果有人习惯用 IDE 或客户端去连 Redishost 模式下所有端口直接暴露在宿主机网络上没有一层 NAT 隔离安全性相对弱一些。当然这取决于你的运维规范这里不展开。2.2 方案二bridge 网络 固定 IP最像物理机部署既然 host 模式端口冲突那我一开始想的是给每个容器分配一个自定义网络里的固定 IP。docker network create redis-cluster-net --subnet172.20.0.0/16然后为每个容器指定--ip 172.20.0.2、--ip 172.20.0.3这样的地址。这样做的优点是容器 IP 固定Redis 的bind和cluster-announce-ip都可以直接写这个 IP节点间通信非常稳定。你不需要做端口映射因为自定义网络内的容器之间可以直接通过固定 IP 访问。但这个方案有个隐藏的问题如果你需要从宿主机外部比如你的开发机访问这个集群就得给每个容器做端口映射。一旦做端口映射端口内外不一致的问题又回来了你还是得靠cluster-announce-port去补救。而且每个容器都要先设置固定 IP 再映射端口docker-compose 文件会非常啰嗦。我后来测试下来的感受是固定 IP 方案最接近物理机部署链路干净适合你对 Docker 网络比较熟、能接受手动配置复杂度的场景。2.3 方案三端口映射 cluster-announce 配置最终我用的方案最后我选用的是最符合日常 Docker 使用习惯的方案每个容器映射不同端口到宿主机然后用cluster-announce-ip等参数把集群间通信的“对外身份”固定下来。具体的端口规划如下表节点角色容器名称Redis 端口Cluster Bus 端口宿主机映射端口master-1redis-master-17001170017001:7001master-2redis-master-27002170027002:7002master-3redis-master-37003170037003:7003slave-1redis-slave-17004170047004:7004slave-2redis-slave-27005170057005:7005slave-3redis-slave-37006170067006:7006这里解释一下 Cluster Bus 端口Redis Cluster 节点之间除了常规的客户端通信端口还有一个额外的总线端口用于集群内部消息握手、心跳、故障检测。它的默认规则是主端口 10000。也就是说 Redis 端口是 7001总线端口就是 17001。在 Docker 环境里如果你不改这个参数容器内的 17001 和宿主机映射的 17001 也要对上。所以我在实际配置里显式写了cluster-announce-bus-port保证总线消息能穿透容器网络。最终我的启动参数核心部分长这样docker run -d \ --name redis-master-1 \ -p 7001:7001 \ -p 17001:17001 \ -v /data/redis/7001:/data \ redis:7.0.12 \ redis-server \ --port 7001 \ --cluster-enabled yes \ --cluster-config-file nodes-7001.conf \ --cluster-node-timeout 5000 \ --appendonly yes \ --cluster-announce-ip 192.168.31.88 \ --cluster-announce-port 7001 \ --cluster-announce-bus-port 17001那这个192.168.31.88是什么就是宿主机的局域网 IP。因为端口映射之后外部访问的入口是宿主机 IP所以我让集群里所有节点都通告宿主机 IP 和对应的映射端口。这样无论容器内部 IP 怎么变只要我没动启动参数集群成员之间的“联系方式”就永远是稳定的宿主机 IP:端口。注意如果你的宿主机 IP 会变比如 DHCP 分配那cluster-announce-ip也要跟着改。为了避免这个问题生产建议用固定 IP 或专门的 DNS 名称。3. 哨兵模式 vs 集群模式为什么我不选择“主从 哨兵”动手之前我还纠结过一个点到底是搭传统的“Redis 主从 Sentinel 哨兵”还是直接上 Redis Cluster这两个方案很常见网上相关的观点也比较多热词里也经常出现“redis 哨兵模式和集群模式的区别”。这里我必须先做个对比因为选错了方向后面全白干。3.1 哨兵模式适合什么场景哨兵模式解决的核心问题是自动故障转移。你有一个主节点、一个或多个从节点Sentinel 进程持续监控主从状态。一旦主节点挂了Sentinel 会选举一个新的主节点然后把从节点重新指向新主节点。客户端通过 Sentinel 获取当前主节点地址实现高可用。但它有两个明显的限制第一所有的数据仍然只在一个主节点上写入主节点的写能力就是整个系统的上限。第二Sentinel 本身只是监控和切换不会帮你做数据分片内存上限还是单机的物理内存上限。如果你只是想解决“Redis 挂了自动切换”的问题数据量不大、并发写不高那哨兵模式完全够用而且运维复杂度比 Cluster 低不少。3.2 集群模式的关键差异Redis Cluster 不只是高可用它加上了数据分片。整个集群的数据被分成 16384 个哈希槽每个主节点负责一部分槽位。当你写入某个 key 时客户端通过对 key 做 CRC16 运算得到一个槽位编号然后跳转到负责该槽位的节点读写。这样带来的好处是多个主节点可以同时承担写请求整体容量和吞吐量可以横向扩展。当你需要扩容时把一部分槽位从旧节点迁移到新节点就完成了数据重分布。同时每个主节点还带从节点一旦主节点挂了它的从节点会被提升为新主节点保证槽位始终有服务。这个模式的缺点也很明显运维复杂度高客户端必须支持集群协议处理 MOVED 重定向、ASK 重定向等异常。有些老项目的客户端库并不方便开启集群模式。另外如果你只有一个 key 需要高频读写集群并不会让这个 key 的性能变好因为单个 key 只落在固定的槽位和节点上。3.3 我的选择逻辑回到我的场景数据看板项目里有大量的用户行为指标天然适合按用户 ID 或业务类型分片。随着业务增长我需要的不只是高可用还有可扩展的写能力和更大的总内存。所以最终决定用 Redis Cluster而且是 3 主 3 从的经典结构。这里额外说一句很多教程会直接让读者用redis-cli --cluster create一句命令创建集群但那是基于单机所有节点在同一个网络环境下的假设。在 Docker 环境里我强烈建议你先手动把六个容器的网络连通性验证好了再执行集群初始化否则失败后排查起来会非常痛苦。4. 环境准备与六节点启动一步步把容器跑起来在实际操作之前先把基础环境说明白。我用的宿主机是 LinuxDocker 版本 24.0 以上镜像版本选了redis:7.0.12。选择这个版本的原因是 7.x 版本对 Cluster 的支持比较成熟原生的集群管理命令也比 5.0 时代友好很多。4.1 关闭防火墙限制与确认端口可用这一步看起来简单但特别容易忽略。Docker 容器端口映射之后宿主机防火墙如果拦住了对应端口集群节点之间就无法通信。# 检查端口是否被占用 ss -lntp | grep -E 7001|17001如果端口被占先释放或者换个端口。我的习惯是用7001-7006加对应的17001-17006作为集群预留端口段既好记也方便后续维护。4.2 用 one by one 方式启动六个容器我刚开始用 docker-compose 一键启动六个服务确实省事但出了问题很难定位是哪个容器起晚了导致集群初始化失败。后来改成按顺序逐个启动并在启动后检查日志确认 Redis 是否正常进入 cluster 模式。下面是我为 master-1 准备的详细启动命令其他节点类似只需替换端口和目录docker run -d \ --name redis-master-1 \ --restart unless-stopped \ -p 7001:7001 \ -p 17001:17001 \ -v /data/redis/7001:/data \ redis:7.0.12 \ redis-server \ --port 7001 \ --cluster-enabled yes \ --cluster-config-file nodes-7001.conf \ --cluster-node-timeout 5000 \ --appendonly yes \ --appendfsync everysec \ --save 900 1 \ --save 300 10 \ --save 60 10000 \ --cluster-announce-ip 192.168.31.88 \ --cluster-announce-port 7001 \ --cluster-announce-bus-port 17001参数说明一下--cluster-enabled yes开启集群模式--cluster-config-file集群节点配置文件。默认会在/data目录下生成--cluster-node-timeout 5000节点超时时间单位毫秒。超过这个时间没收到心跳就认为节点有故障--appendonly yes--appendfsync everysec开启 AOF 持久化每秒刷盘兼顾可靠性和性能--save系列开启 RDB 快照策略配合 AOF 双保险--cluster-announce-*前面反复强调的网络通告配置其他五个节点的命令完全一致把端口、目录、容器名替换掉即可。比如 master-2docker run -d \ --name redis-master-2 \ --restart unless-stopped \ -p 7002:7002 \ -p 17002:17002 \ -v /data/redis/7002:/data \ redis:7.0.12 \ redis-server \ --port 7002 \ --cluster-enabled yes \ --cluster-config-file nodes-7002.conf \ --cluster-node-timeout 5000 \ --appendonly yes \ --appendfsync everysec \ --save 900 1 \ --save 300 10 \ --save 60 10000 \ --cluster-announce-ip 192.168.31.88 \ --cluster-announce-port 7002 \ --cluster-announce-bus-port 170024.3 启动后检查容器状态六个容器都启动之后不要急着创建集群先确认每个容器的 Redis 进程状态和监听端口。docker ps | grep redis-在宿主机上执行redis-cli -p 7001 cluster info如果返回cluster_state:fail是正常的因为集群还没初始化。但至少说明端口是通的Redis 进程已经进入集群模式。这一步验证很重要可以提前发现端口映射或配置问题而不是等创建集群时一起报错。4.4 关于 Docker Desktop 与 Windows/Mac 环境的一点提醒热搜词里有“docker desktop 安装”“virtualization support not detected 无法启动”这些说明不少朋友的 Docker 环境本身就有问题。如果你用的是 Docker Desktop注意两点第一Windows 下要把 Docker Desktop 的 WSL2 后端打开否则容器网络会走 Hyper-V 的 NAT 模式内部 IP 段比较特殊和 Redis Cluster 的通告机制容易冲突。第二Mac 下 Docker 的网络模式是虚拟化的容器之间是互通但外部访问要依赖端口映射所以我的cluster-announce-ip方案在 Mac 上同样适用。如果你的 Docker Desktop 一直报 Virtualization support 相关错误通常是 BIOS 里没开启虚拟化。这个属于环境问题网上相关资料也很多解决完再回来继续。5. 集群初始化的两种方式官方一键脚本与手动 meet六个容器都准备好了接下来就是最核心的一步把六个节点组成一个集群。这里有两个路线可以走我两个都试过结果开发效率和排错体验差异很大。5.1 方式一redis-cli --cluster create 一条命令完成如果你用的是 redis:7.x 镜像可以直接在一台能访问宿主机映射端口的机器上执行redis-cli --cluster create \ 192.168.31.88:7001 \ 192.168.31.88:7002 \ 192.168.31.88:7003 \ 192.168.31.88:7004 \ 192.168.31.88:7005 \ 192.168.31.88:7006 \ --cluster-replicas 1这个命令会自动做主从分配、槽位分配交互式询问是否接受分配计划输入yes就完成。整个过程一气呵成。但很多人在这一步会卡住因为这条命令要求执行端能访问到所有节点的 Redis 端口和 Cluster Bus 端口。如果redis-cli工具本身不在宿主机上而是放在容器里那容器访问宿主机映射端口时可能会有 NAT 差异。我当时的做法是直接在本机安装一个 redis-tools 包来执行集群初始化命令。因为宿主机访问自己映射的端口最直接不会有容器间通信的干扰。# Ubuntu/Debian apt-get install -y redis-tools # CentOS/Rocky dnf install -y redis注意CentOS 系列默认包名叫redis安装后也会带上redis-cli。5.2 方式二手动 cluster meet逐个节点添加如果你不想用一键脚本或者你用的 Redis 版本比较老5.0 之前就需要手动方式redis-cli -p 7001 cluster meet 192.168.31.88 7002 redis-cli -p 7001 cluster meet 192.168.31.88 7003 ...这样每个节点会逐步被7001节点认识并最终形成全互联的集群拓扑。但手动方式有个麻烦它不会自动分配槽位也不会自动分配从节点。你得手动给每个主节点分配槽位范围手动给主节点指定从节点非常繁琐。我的建议是除非你在排查故障或者测试特殊拓扑否则直接用redis-cli --cluster create它内部会自动做节点握手、槽位分配、从节点配对比手动方式可靠得多。5.3 初始化完成后立即验证集群创建成功后用下面的命令快速验证redis-cli -p 7001 cluster info redis-cli -p 7001 cluster nodes redis-cli -p 7001 cluster slotscluster info里cluster_state:okcluster_nodes能看到 6 个节点cluster_slots显示 16384 个槽位全部分配完成说明集群已经可用了。这里说一个小细节cluster nodes输出的每行格式是“节点ID 地址:端口 角色 状态 槽位”地址部分显示的应该都是192.168.31.88:700X。如果还显示172.17.0.x:700X之类的容器内部 IP说明cluster-announce-ip没有生效集群内部通讯会有问题即使当前能 work容器重启后大概率会失联。6. 故障转移实测我直接 kill 掉一个主节点集群搭好之后不做一次真实的故障转移测试就相当于写完了代码没跑测试。这里我完整记录一次主节点宕机后集群的响应过程以及我观察到的现象和注意事项。6.1 选定测试主节点并准备观测指标我的三个主节点分别是 7001、7002、7003。为了不影响测试环境下别的业务我选择了 master-37003作为故障对象。先记录下它当前从节点是哪个以及它负责的槽位范围redis-cli -p 7003 cluster nodes | grep master输出中应该能看出 7003 的从节点是哪个。也可以直接看cluster slots命令它会列出每个槽范围对应的主节点和从节点。6.2 模拟主节点宕机直接停掉容器docker stop redis-master-3这样比在容器里执行redis-cli shutdown更接近真实的物理宕机场景进程被强制终止不会优雅地通知其他节点。然后每隔几秒检查一次集群状态redis-cli -p 7001 cluster info第一次几秒内可能看到cluster_state:fail这是正常的因为cluster-node-timeout设置为 5000 毫秒其他节点发现 7003 失联需要一些时间。大概 5 到 10 秒之后再执行redis-cli -p 7001 cluster nodes你会看到原来 7003 的从节点状态从slave变成了master并且它接管了原来 7003 负责的所有槽位。同时整个集群的cluster_state恢复为ok。6.3 写入数据验证主从切换用 redis-cli 连接集群并写入一个 keyredis-cli -c -p 7001 set test-key hello redis-cli -c -p 7001 get test-key-c参数会让客户端自动跟随集群重定向。如果写入和读取都成功说明集群的槽位服务已经由新的主节点接管数据链路没有问题。如果集群分片逻辑正确这个 key 会落到某个槽位。这个槽位原来的主人是 7003现在则由 7003 的从节点新的主节点提供读写服务。6.4 恢复宕机节点并观察其角色变化故障测试完成后把刚才停掉的容器重新启动docker start redis-master-3容器启动后Redis 进程起来它会尝试重新加入集群。因为此时原本它负责的槽位已经被它的从节点接管它会发现自己的主节点身份已经没了于是自动以从节点的身份挂到新的主节点下面继续做数据同步。经过测试即使容器 IP 有变化由于我们用的是宿主机 IP 通告节点重新加入集群依然能正常握手。这里有个容易忽略的点容器重启后AOF 和 RDB 持久化文件还在/data目录里节点会基于这些文件恢复数据。所以放心重启即可不必担心数据丢失。7. 日常维护集群重启、扩容与槽位迁移注意事项集群能用只是开始真正考验人的是后面的日常维护。这一节是我在实际操作里最有价值的部分因为很多细节不跑一遍根本不会知道。7.1 容器重启顺序从节点优先主节点确认角色如果你的宿主机重启了所有容器都会跟着起来。由于 Docker 本身的启动顺序不保证可能会出现六个容器同时启动但彼此还没完全就绪的情况。我的做法是在宿主机启动后写一个简单的启动脚本按顺序依次启动容器docker start redis-slave-1 redis-slave-2 redis-slave-3 sleep 10 docker start redis-master-1 redis-master-2 redis-master-3先启动从节点再启动主节点可以避免由于主节点先启动后立即尝试联系从节点而捉急等待超时的情况。当然即使启动顺序不理想Redis 集群的节点发现机制也能在后续通过心跳逐步恢复只是等待时间会拉长。为了省事我还是建议保持这个顺序。启动完成后执行cluster info确认cluster_state:ok。如果某个节点丢了自己的节点文件比如/data目录被清了它可能无法重新加入集群这时候最简单的方法就是重新加入甚至重建节点具体在故障排查里单独说。7.2 扩容新增一个主节点并迁移槽位测试集群规模不够的时候可能想加节点。Redis Cluster 支持动态扩容但流程比创建集群稍微复杂一点。第一步先启动一个新容器作为新节点比如 7007docker run -d \ --name redis-master-4 \ -p 7007:7007 \ -p 17007:17007 \ -v /data/redis/7007:/data \ redis:7.0.12 \ redis-server \ --port 7007 \ --cluster-enabled yes \ --cluster-config-file nodes-7007.conf \ --cluster-node-timeout 5000 \ --appendonly yes \ --cluster-announce-ip 192.168.31.88 \ --cluster-announce-port 7007 \ --cluster-announce-bus-port 17007第二步把新节点加入集群redis-cli -p 7001 cluster meet 192.168.31.88 7007此时 7007 在集群里但还没有分配任何槽位。你现在看cluster nodes它显示master但是槽位为空。第三步把一部分槽位迁移过去redis-cli --cluster reshard 192.168.31.88:7001这个命令会交互式问你迁移多少个槽位、把槽位迁到哪个节点 ID、从哪些源节点取槽。比如我想从三个旧主节点各迁 500 个槽一共 1500 个槽给新节点就在提示How many slots do you want to move时输入 1500在What is the receiving node ID时输入 7007 的节点 ID在Source node时依次输入三个旧节点的 ID最后输入done。7.3 缩容和节点下线先把槽位搬走再 remove 节点扩容讲完顺便说一下缩容。下线一个节点前你必须先把它的槽位搬到其他节点否则集群会处于异常状态。操作用reshard只是方向是“从下线节点搬出槽位到别的节点”。搬完空槽后再从集群里移除这个节点redis-cli --cluster del-node 192.168.31.88:7001 node-id-of-down-node最后停掉并删除容器docker stop redis-master-4 docker rm redis-master-4这套流程做完集群规模又回到了原来的样子业务无感知。我自己当时还验证过迁移槽位过程中读写不会中断Redis 会在客户端收到 MOVED 错误后自动重定向只要客户端支持集群模式即可。7.4 槽位迁移期间的性能提醒在扩容或缩容期间迁移槽位会涉及到大量 key 的序列化传输和删除操作。如果你的集群在线业务繁忙建议在低峰期操作。另外迁移时单个大 key 会导致迁移时间较长甚至阻塞源节点。所以如果有特别大的 value最好提前拆分或规划好槽位避免迁移时性能抖动。8. 高频故障排查清单从端口不通到集群恢复这部分是我踩坑和排错最多的地方直接列一个排查清单方便你对照。现象可能原因排查方法解决方案cluster_state:fail某个节点失联或者槽位没有完全分配redis-cli -p 7001 cluster nodes查看节点状态检查对应容器是否存活kill 恢复或重新加入集群节点无法通信防火墙阻断端口或容器内部 IP 不一致在宿主机执行nc -vz 192.168.31.88 7001在容器内redis-cli -p 7001 ping调整防火墙或检查cluster-announce-ip配置创建集群时提示节点存在旧的nodes-*.conf里记录了过期节点信息查看/data/nodes-*.conf内容删除旧配置文件后重启容器写入 key 报 MOVED客户端没开集群模式检查客户端配置使用支持 cluster 的客户端列表修改客户端参数容器重启后节点角色变化主节点数据落后或从节点接管了槽位cluster nodes查看角色变化如果不想要新角色可以手动cluster failover切换回来Redis 容器启动失败端口被占用宿主机端口被其他进程占用ss -lntpgrep 70018.1 最常见的问题容器重启后节点“失忆”我在实际测试中发现如果你在创建集群之后修改过容器的端口映射或者清空了/data目录重启容器后节点虽然使用相同的cluster-announce-ip但可能因为持久化文件丢失而找不到原来的集群。解决方法是不要轻易清空/data目录。如果确实丢了最简单的方式是重新把它作为新节点加入集群。对主节点来说加回来时如果槽位已经被其他节点接管它会自动变成从节点或单纯的空主节点对从节点来说重新加入后会触发全量同步。8.2 Docker 网络不通时的排查链路热词里也有“docker 网络不通”这个词说明这确实是大家的痛点。我遇到过一种情况容器之间能 ping 通但 Redis 集群握手超时。问题出在docker0网桥的 iptables 规则上。当你使用端口映射时Docker 会在 iptables 里加规则但这些规则偶尔会和宿主机的自定义防火墙规则冲突。此时的排查顺序是先看容器日志docker logs redis-master-1再看宿主机防火墙firewall-cmd --list-all或ufw status最后通过tcpdump -i any port 17001抓包看集群总线的消息是否到达宿主机。如果发现总线端口被防火墙拦截放行即可firewall-cmd --permanent --add-port7001-7006/tcp firewall-cmd --permanent --add-port17001-17006/tcp firewall-cmd --reload8.3 一点建议容器编排别急着上 Kubernetes顺着热词里出现“kubernetes 基于 docker 的高可用集群安装”之类的说法我多说一句。如果你只是想在测试环境快速验证 Redis Cluster直接在 Docker 里手动操作完全够用不用一上来就上 Kubernetes。等你把 Docker 方案跑通了对 Redis Cluster 的节点发现、槽位迁移、故障恢复都有了直观理解再考虑容器编排会更顺。我自己后续也在梳理如何用 Docker Compose 把这套方案固化下来方便团队其他人一键拉起但核心网络参数配置和这套手动方案一致。如果你需要给别人交付建议把cluster-announce-ip写成变量避免每台机器都改一遍配置。9. 写在最后Docker 化 Redis 集群的几个实用体会这趟实操下来我最深的感受是Redis Cluster 本身并不难难的是环境网络模型和一些隐藏约定。只要你理解了端口、总线、通告 IP 这三者的关系后面所有步骤都是水到渠成。再分享一个小技巧创建集群之前先在宿主机上用redis-cli -p 7001 ping逐个验证端口连通性然后再用redis-cli --cluster create。这一步虽然简单但能帮你把“端口不通”和“集群配置错误”两类问题分开处理避免一次踩两个坑。最后提醒一句如果你的生产环境网络策略比较严格或者未来有跨机房部署的需求Redis Cluster 的节点发现机制会带来额外的运维负担。可以考虑用 Kubernetes 环境下的 Operator 方案来管理或者使用云厂商托管的 Redis 集群服务。但不管用哪种方式本文里这套 Docker 验证和排错思路对你理解底层原理一定有帮助。至少我自己现在对 Redis Cluster 的机制算是彻底摸透了。