
简介面向 CentOS 7.x 环境下需要快速搭建 Redis 集群的运维与开发人员这份资源提供了一套基于 Docker 的一键部署方案通过 shell 脚本把镜像导入、容器编排与集群初始化串联起来省去手工逐节点配置的繁琐过程。压缩包共 6 个文件约 22.46MB以 sh 脚本为主体配合 tar 镜像包、conf 配置文件和 md 说明文档分别承担自动化部署、离线镜像导入、参数配置与使用指引等职责按说明传入参数即可自动执行部署流程。目前已有 1055 人学习下载说明该方案在实际环境中具备一定参考价值。读者可获得可直接复用的部署脚本与配套配置理解脚本如何组织多节点容器与集群创建逻辑并借助说明文档与卸载脚本完成环境清理适合作为学习 Docker 编排与 Redis 集群搭建的实践素材。1. 用一份 shell 脚本把 Redis 集群塞进 DockerCentOS 7 上的落地路径手上只有两三台 CentOS 7 的机器业务侧又催着要一套能读写、能故障转移的 Redis 集群这时候从零手写节点配置、逐个docker run、再手动redis-cli --cluster create一套流程走下来少说半小时还容易在端口映射和集群总线地址上翻车。这份 docker 一键部署 Redis 集群的 shell 脚本解决的就是这个场景把节点创建、配置生成、集群握手、槽位分配打包成一条命令跑完就能拿到一个可用的三主三从集群。它适合两类人——需要快速搭测试环境的后端开发以及要在内网批量铺 Redis 集群的运维。前提是宿主机为 CentOS 7.x已装好 Docker且对 Redis 集群的基本概念不陌生。下面按「脚本干了什么 → 怎么改参数 → 哪里会炸」的顺序拆开讲。2. 脚本拆解六个节点是怎么被拉起来并组成集群的2.1 集群拓扑与端口规划Redis 集群的最小可用形态是三主三从脚本默认就是 6 个容器、6 个端口。每个节点需要两个端口一个客户端端口默认 7000 起一个集群总线端口客户端端口 10000即 17000 起。这个 10000 的偏移是 Redis 的硬规则不是脚本随便定的改端口时总线端口必须同步跟着变否则节点之间永远握手不上。脚本里通常用两个循环变量控制节点序号i从 0 到 5客户端端口PORT$((7000i))总线端口BUS_PORT$((PORT10000))。容器名一般拼成redis-node-$i数据目录挂到宿主机/data/redis/node$i。这套命名不是强制的但保持「序号—端口—目录」三者对齐后面排查时能少绕很多弯。节点客户端端口总线端口角色默认分配node0700017000masternode1700117001masternode2700217002masternode3700317003slavenode4700417004slavenode5700517005slave需要说明的是脚本只负责把 6 个节点拉起来并执行--cluster create主从关系由 Redis 自己按顺序分配前三个成为主、后三个成为各自的从。想指定谁当谁的主得在create之后用cluster replicate手动调脚本一般不做这层。2.2 每个节点的 redis.conf 关键项容器能起来不代表集群能成真正决定成败的是每个节点挂进去的配置文件。脚本会在启动容器前用 heredoc 或cat 给每个节点生成一份redis.conf核心就这几行# 生成单节点配置$PORT 为当前节点客户端端口 cat /data/redis/node${i}/redis.conf EOF port ${PORT} cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 15000 appendonly yes protected-mode no daemonize no EOF逐项说清楚为什么这么写。cluster-enabled yes是集群模式的开关缺了它节点就是个普通单机 Rediscluster create会直接报节点不支持集群。cluster-config-file nodes.conf是节点自己维护的集群状态文件必须可写且每个节点独立一份绝不能多个节点共用同一个路径否则集群元数据互相覆盖表现为节点反复重启后集群散架。cluster-node-timeout 15000是故障判定窗口15 秒是常见折中值设太小网络抖一下就触发主从切换设太大故障转移慢测试环境 15000 够用。protected-mode no在容器网络里是必须的否则 Redis 只监听回环、拒绝外部连接宿主机根本连不进去。appendonly yes打开 AOF集群环境下重启恢复更可靠代价是磁盘写入多一些。daemonize no这一项容易被忽略容器里必须前台运行如果写成 yes容器启动后主进程立刻退出docker ps里看不到节点日志里却没有任何报错属于典型的「静默翻车」。2.3 docker run 的参数与网络模式选择节点配置就绪后脚本对每个节点执行一次docker run。这里有个关键决策用 host 网络还是端口映射。集群模式下节点之间要互相通告自己的地址和总线端口如果用默认 bridge 网络加-p映射容器内部看到的 IP 是 172.x 网段通告出去后其他节点和客户端都连不上集群永远处于cluster_state:fail。所以脚本一般直接用--net host# 以 host 网络启动节点端口即宿主机端口 docker run -d \ --name redis-node${i} \ --net host \ -v /data/redis/node${i}:/data \ -v /data/redis/node${i}/redis.conf:/usr/local/etc/redis/redis.conf \ redis:6.2 \ redis-server /usr/local/etc/redis/redis.conf--net host让容器直接复用宿主机网络栈redis.conf里的port 7000就是宿主机 7000总线端口 17000 也天然可达省掉了端口映射和地址通告的所有麻烦。代价是端口不能冲突一台机器上跑这套脚本前先确认 7000-7005 和 17000-17005 没被占用。-v挂两处数据目录保证容器重建后数据还在配置文件挂进去让容器读的是脚本生成的那份而不是镜像默认配置。镜像 tag 建议锁死具体小版本如redis:6.2别用latest不同大版本的集群协议细节有差异混用容易出玄学问题。2.4 集群握手cluster create 与槽位分配六个容器都Up之后脚本最后一步是执行集群创建。常见写法是等几秒让节点完成启动再调redis-cli --cluster create# 等待节点就绪后创建集群--cluster-replicas 1 表示每主一从 sleep 5 docker exec -i redis-node0 redis-cli --cluster create \ 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \ 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \ --cluster-replicas 1--cluster-replicas 1的含义是每个主节点配一个从6 个节点正好三主三从。命令执行时会要求输入yes确认槽位分配方案脚本里通常用echo yes |或--cluster-yes参数跳过交互。槽位是 Redis 集群的核心16384 个槽平均分给三个主客户端按 key 的 CRC16 取模决定去哪个节点所以集群建好后cluster info里cluster_state必须是ok、cluster_slots_assigned必须是 16384少一个槽都算没建完。握手阶段最常见的失败是「节点互相看不见」报错形如Node 127.0.0.1:7000 is not empty或Can I set the above configuration? (type yes to accept): ERR Invalid node address specified。前者多半是节点目录里残留了旧的nodes.conf集群以为这个节点已经属于别的集群后者通常是地址写成了容器名或错误 IP。脚本能一键跑通的前提是每次重建前把旧数据目录清干净这一点在避坑章节会展开。3. 参数怎么改端口、密码、超时与资源限制3.1 改端口段与节点数量脚本顶部的变量区一般长这样改集群规模就动这里# 集群基础参数按需修改 BASE_PORT7000 # 起始客户端端口 NODE_COUNT6 # 节点总数必须是 3 的倍数 PASSWORDYourPass123 # 集群密码留空则不启用 DATA_ROOT/data/redis # 宿主机数据根目录NODE_COUNT必须是 3 的倍数因为 Redis 集群要求至少三个主节点才能投票选主6 节点是三主三从9 节点是三主六从或按--cluster-replicas重新分配。把NODE_COUNT改成 9 时--cluster-replicas要相应调整否则create会报节点数与副本数不匹配。BASE_PORT改动后总线端口自动跟着10000不用单独改但宿主机防火墙和 SELinux 要放行新端口段CentOS 7 默认开着 firewalldfirewall-cmd --add-port7000-7008/tcp这类放行别漏。3.2 给集群加密码生产或半生产环境必须加密码脚本里对应在redis.conf追加两行并在cluster create时带上认证# 配置文件中启用密码 echo requirepass ${PASSWORD} /data/redis/node${i}/redis.conf echo masterauth ${PASSWORD} /data/redis/node${i}/redis.confrequirepass是客户端连接密码masterauth是从节点连主节点时用的密码两个都要设只设前者会导致主从复制认证失败、从节点一直master_link_status:down。加密码后cluster create命令要改成redis-cli -a ${PASSWORD} --cluster create ...后续所有cluster子命令和客户端连接也都得带-a。注意-a在命令行里会触发「不安全的密码传递」警告测试环境可忽略正式环境建议用REDISCLI_AUTH环境变量传避免密码进 shell history。3.3 超时与资源限制的取舍cluster-node-timeout前面给了 15000这个值要结合部署环境调。单机多容器、宿主机负载不高时10000-15000 都稳如果宿主机上还跑着别的重负载服务容器偶尔被调度卡顿超时设太小会误判主节点下线触发不必要的切换日志里能看到Marking node ... as failing反复出现。反过来设到 30000 以上真故障时切换要等半分钟业务侧感知明显。我的习惯是测试环境 15000、压测环境 20000先跑一轮人为docker stop主节点看从节点多久接管再决定要不要微调。资源限制方面docker run可以加--memory 512m --cpus 1但要注意 Redis 集群每个节点都持有部分槽位数据内存给小了容易触发 maxmemory 淘汰甚至 OOM。6 节点单机部署时宿主机内存至少留 4G 给这套集群别把--memory压到 256m 以下否则节点启动后加载 AOF 就可能被 kill表现为容器反复重启、docker logs里只有一行Killed。4. 避坑与排查五个让集群起不来的真实原因4.1 现象cluster_state 一直是 fail槽位显示 0原因几乎都是cluster create没真正执行成功或者执行了但节点地址通告错误。先docker exec redis-node0 redis-cli -p 7000 cluster info看cluster_state和cluster_slots_assigned如果是fail且槽位为 0说明集群压根没建。再cluster nodes看节点列表如果每个节点都只看到自己就是握手没成。解决确认--net host生效docker inspect看 NetworkMode 是否为 host确认cluster create的地址用的是宿主机可达 IP 而非容器名清空所有节点数据目录后重跑脚本。4.2 现象节点启动即退出日志无报错前面提过的daemonize yes是头号嫌疑容器要求前台进程配置成后台运行主进程立刻退出。其次是配置文件路径挂错容器读的是镜像默认配置而非脚本生成的那份cluster-enabled没生效。排查方法docker logs redis-node0看最后几行如果只有启动 banner 没有Ready to accept connections基本就是配置没读到。解决确认-v挂载的宿主机路径与容器内redis-server参数路径一致daemonize保持no。4.3 现象重建集群时报 Node is not empty旧集群的nodes.conf残留在数据目录里新集群启动时节点带着旧身份cluster create认为它已属于别的集群。这是反复调试时最高频的坑。解决脚本重建前必须rm -rf /data/redis/node*或者至少删掉每个目录下的nodes.conf和appendonly.aof。血泪经验是别图省事只删容器不删目录docker rm -f之后数据目录还在下次启动照样带着旧集群元数据。4.4 现象主从复制断开从节点 master_link_status 为 down加密码后只配了requirepass没配masterauth从节点连主节点被拒。或者主从之间网络不通host 网络下一般是防火墙拦了总线端口。排查docker exec redis-node3 redis-cli -p 7003 -a 密码 info replication看master_link_statusdown时再看master_last_io_seconds_ago是否持续增大。解决补上masterauth确认 17000-17005 端口在宿主机防火墙放行SELinux 若为 enforcing 需确认容器挂载目录有正确上下文。4.5 现象客户端能连单节点但 MOVED 重定向失败客户端没开集群模式或者连的节点地址是 127.0.0.1 而客户端在另一台机器。集群返回MOVED重定向时客户端要能连到重定向目标地址如果节点通告的是 127.0.0.1外部客户端拿到这个地址自然连不上。解决确保cluster create时用的是宿主机对外 IP或在客户端侧使用支持集群模式的 SDK如 Jedis 的JedisCluster、redis-py 的RedisCluster让客户端自己处理重定向。单机测试用redis-cli -c -p 7000加-c参数即可跟随重定向。5. 验证与进阶用一条命令确认集群真的可用集群建完不等于能用得跑一轮读写和故障转移验证。先做基础连通性检查确认槽位和节点角色符合预期# 查看集群整体状态与节点角色 docker exec -i redis-node0 redis-cli -p 7000 -a 密码 cluster info | grep -E cluster_state|cluster_slots_assigned docker exec -i redis-node0 redis-cli -p 7000 -a 密码 cluster nodescluster_state:ok且cluster_slots_assigned:16384是硬指标cluster nodes输出里应该看到三个 master 各带一段槽位范围、三个 slave 分别slave于对应 master。接着做跨槽读写验证重定向链路# -c 开启集群模式key 落在不同槽位时自动跟随重定向 docker exec -i redis-node0 redis-cli -c -p 7000 -a 密码 set foo bar docker exec -i redis-node0 redis-cli -c -p 7000 -a 密码 set hello world docker exec -i redis-node0 redis-cli -c -p 7000 -a 密码 get foo如果set返回MOVED后客户端没自动跳转说明-c没生效或客户端不支持集群这一步能提前暴露客户端选型问题。最后做故障转移演练docker stop redis-node0等cluster-node-timeout过后cluster nodes里 node0 应标记为fail其从节点node3升为 master 接管槽位再set/get验证读写不中断。恢复时docker start redis-node0它会以 slave 身份重新加入。进阶用法上脚本跑通后可以把「清目录 → 起容器 → 建集群 → 验证」串成一个带set -e的完整流程任何一步失败立即退出并打印当前cluster info避免半成品集群留在机器上。参数化方面把BASE_PORT、NODE_COUNT、PASSWORD抽到独立的cluster.env里source进来同一份脚本就能在测试和生产用不同配置跑。镜像版本建议在脚本里写死并加注释说明为什么锁这个版本别让半年后的自己对着latest猜当时的环境。从那以后我每次跑这类一键脚本都会在cluster create之后强制加一段cluster info断言状态不是ok就直接exit 1宁可脚本报错也不留一个「看起来起来了其实不能用」的集群。希望这套拆解帮到你少在端口和 nodes.conf 上翻车。本文还有配套的精品资源点击获取