简介:这份资源面向需要在 CentOS 7.x 环境下快速搭建 Redis 集群的运维与后端开发人员,提供基于 Docker 的一键部署方案,省去手工配置节点、拉取镜像与逐个启动容器的繁琐流程。压缩包共 6 个文件,以 3 个 shell 脚本为主,配合 1 个 Redis 配置文件、1 个离线镜像 tar 包和 1 份说明文档,整体约 22.46MB,脚本负责自动构建与部署,配置文件用于集群参数调整,镜像包便于无外网环境直接导入使用。使用时按说明将参数传入安装脚本即可自动执行部署程序,作者亲测可用,同时附带卸载脚本方便环境清理与重复实验。目前已有 1055 人学习下载,适合希望快速验证 Redis 集群方案、减少重复搭建成本的技术人员参考。
1. 从一台裸机到三主三从:这套脚本到底省掉了哪些手工活
如果你在 CentOS 7.x 上手工搭过一次 Redis 集群,大概率经历过这样的流程:装 Docker、拉镜像、给六个节点分别写配置文件、算 cluster meet 的 IP 和端口、等节点握手、分配 16384 个槽位、再给每个主节点挂一个从节点。整套动作敲下来,命令少说三四十条,中间任何一步端口写错或者槽位没分干净,cluster info就会一直卡在fail状态。这套「docker 一键部署 redis 集群 shell 脚本」要解决的,就是把上面这一长串重复劳动压缩成一条命令。它面向的是 CentOS 7.x 环境,用 Docker 跑容器,用 shell 脚本编排三主三从的集群拓扑,适合需要在测试机、内网服务器或者 CI 环境里快速拉起一套 Redis 集群做验证的从业者。你不需要提前理解槽位分配的全部细节,但需要知道脚本在背后替你做了什么,否则出了问题连日志该看哪个容器都不清楚。
2. 脚本的骨架:三主三从拓扑与 Docker 网络怎么落地
2.1 为什么是六个容器而不是三个
Redis Cluster 的最小可用形态是三主三从,共六个节点。三个主节点负责分摊 16384 个哈希槽,三个从节点各自复制一个主节点。脚本选择六个独立容器而不是单容器多实例,核心原因是隔离性:每个节点有独立的配置文件、独立的日志、独立的端口映射,某个节点崩了不会连带影响其他节点,排查时docker logs直接定位到具体容器。端口分配上,常见做法是从 7001 到 7006 依次递增,每个容器同时暴露客户端端口和集群总线端口(客户端端口 + 10000),也就是 7001 对应 17001,7002 对应 17002,以此类推。集群总线端口用于节点间 gossip 通信,少了它节点永远握不上手。
Docker 网络这块有个容易忽略的点:六个容器必须挂在同一个自定义 bridge 网络上,不能用默认的 bridge。默认 bridge 不支持容器名 DNS 解析,脚本里如果用容器名做cluster meet会直接失败。自定义网络下,容器之间可以用服务名互相访问,脚本内部做节点发现时就不用硬编码 IP,换台机器也不用改配置。
2.2 脚本的核心执行流程拆解
下面这段是脚本主干逻辑的简化版,保留了关键步骤和参数,去掉了日志着色和错误重试的装饰代码。你可以把它理解成脚本的「骨架」,实际脚本会在每个步骤前后加上状态检查和输出。
#!/bin/bash # redis-cluster-deploy.sh # 适用 CentOS 7.x,需提前安装 docker-ce # 参数区:按需修改 REDIS_IMAGE="redis:6.2" CLUSTER_NAME="redis-cluster" NETWORK_NAME="redis-net" BASE_PORT=7001 NODE_COUNT=6 PASSWORD="your_cluster_password" # 集群密码,留空则不启用 # 1. 创建自定义 bridge 网络 docker network create ${NETWORK_NAME} 2>/dev/null || true # 2. 批量启动六个节点 for i in $(seq 0 $((NODE_COUNT-1))); do PORT=$((BASE_PORT + i)) BUS_PORT=$((PORT + 10000)) NODE_NAME="${CLUSTER_NAME}-node-${i}" docker run -d \ --name ${NODE_NAME} \ --net ${NETWORK_NAME} \ -p ${PORT}:${PORT} \ -p ${BUS_PORT}:${BUS_PORT} \ -v /data/redis/${NODE_NAME}:/data \ ${REDIS_IMAGE} \ redis-server \ --port ${PORT} \ --cluster-enabled yes \ --cluster-config-file nodes.conf \ --cluster-node-timeout 5000 \ --appendonly yes \ --requirepass ${PASSWORD} \ --masterauth ${PASSWORD} done # 3. 等待所有节点就绪 sleep 5 # 4. 组建集群:前三个为主,后三个为从 NODES="" for i in $(seq 0 $((NODE_COUNT-1))); do PORT=$((BASE_PORT + i)) NODES="${NODES} ${CLUSTER_NAME}-node-${i}:${PORT}" done docker exec ${CLUSTER_NAME}-node-0 \ redis-cli -a ${PASSWORD} --cluster create \ ${NODES} \ --cluster-replicas 1 \ --cluster-yes这段脚本的逻辑分四层。第一层建网络,docker network create带|| true是为了脚本可重复执行,网络已存在时不报错退出。第二层循环启动容器,每个容器挂载独立的数据目录到宿主机/data/redis/下,这样容器重建数据不丢。--cluster-enabled yes是开启集群模式的总开关,--cluster-config-file nodes.conf让每个节点自己维护集群状态文件,--cluster-node-timeout 5000是节点失联判定时间,单位毫秒,内网环境 5000 够用,跨机房要往上调。--appendonly yes开 AOF 持久化,集群模式下 RDB 和 AOF 可以共存,但 AOF 在节点重启后恢复更可靠。
第三层sleep 5是等 Redis 进程完全起来,实际脚本里更稳妥的做法是轮询redis-cli ping直到返回 PONG,而不是死等固定秒数。第四层是组集群的关键命令,--cluster-replicas 1告诉 Redis 每个主节点配一个从节点,--cluster-yes跳过交互确认。redis-cli --cluster create会自动完成槽位分配和主从关系建立,这也是脚本能「一键」的核心——把手工的cluster meet、cluster addslots、cluster replicate全部封装掉了。
2.3 参数怎么改:端口、密码、持久化路径
脚本暴露出来的可调参数不多,但每个都影响后续使用。端口基址BASE_PORT改成 8001 就是另一套集群,同一台机器上跑多套集群时靠这个区分。密码参数PASSWORD如果留空,--requirepass和--masterauth会传入空字符串,Redis 会当作没设密码处理,但生产环境不建议裸奔。持久化路径/data/redis/${NODE_NAME}建议提前确认宿主机磁盘挂载点,CentOS 7.x 默认根分区往往不大,AOF 文件涨起来很快,挂到独立数据盘更稳妥。
注意:
--cluster-replicas 1这个参数只在cluster create时生效,集群建好之后再想调整主从比例,得手动做 reshard 和 replicate,脚本帮不了你。
3. 跑起来之后:验证集群状态与日常操作
3.1 三条命令确认集群真的可用
脚本执行完不代表集群就健康了,至少要走一遍验证。第一条,进任意节点执行cluster info,看cluster_state是不是ok,cluster_slots_assigned是不是 16384。如果槽位没分满,集群状态会是fail,这时候客户端写入会直接报CLUSTERDOWN。第二条,cluster nodes看节点列表,确认六个节点都在,三个 master 各自带着一个 slave,没有节点处于fail或handshake状态。第三条,实际写一个 key 再读出来,验证数据通路。
# 查看集群整体状态 docker exec redis-cluster-node-0 \ redis-cli -a your_cluster_password -p 7001 cluster info # 查看节点拓扑 docker exec redis-cluster-node-0 \ redis-cli -a your_cluster_password -p 7001 cluster nodes # 写入并读取一个测试 key docker exec redis-cluster-node-0 \ redis-cli -a your_cluster_password -p 7001 -c set testkey hello docker exec redis-cluster-node-0 \ redis-cli -a your_cluster_password -p 7001 -c get testkey注意-c参数,集群模式下必须加,它让 redis-cli 在收到 MOVED 重定向时自动跳转到正确的节点。不加-c的话,你 set 一个 key 可能直接返回 MOVED 错误,新手容易在这里卡住,以为集群没搭好。
3.2 集群模式下的客户端连接差异
单机 Redis 和集群 Redis 在客户端使用上有几个硬性差异,脚本搭好集群只是第一步,业务代码能不能跑通还得看这些。第一,集群模式下不支持多 key 跨槽操作,mget、mset如果涉及的 key 不在同一个槽,会直接报 CROSSSLOT 错误。解决办法是用 hash tag,把相关 key 的{}部分写成一样,比如user:{1001}:name和user:{1001}:age会落到同一个槽。第二,事务和 Lua 脚本同样受槽位限制,涉及多 key 的 Lua 脚本在集群模式下基本没法用。第三,SELECT命令在集群模式下不可用,因为集群只有 db0。
这些限制不是脚本的锅,是 Redis Cluster 本身的设计约束。脚本能帮你把集群拉起来,但业务侧怎么适配集群模式,得提前评估。如果你的业务大量依赖多 key 原子操作,可能单机主从加哨兵更合适,硬上集群反而给自己挖坑。
3.3 扩缩容时脚本的边界在哪
这套脚本的定位是「初始化部署」,不是「集群运维」。集群跑起来之后要加节点、删节点、迁移槽位,脚本不提供这些能力。加节点得手动cluster meet再cluster addslots或者用redis-cli --cluster add-node,删节点要先把槽位迁走再cluster forget。这些操作脚本没覆盖,也不建议硬塞进去,因为扩缩容的决策依赖当前槽位分布和数据量,不是一条固定命令能搞定的。
提示:如果只是测试环境反复重建集群,脚本里可以在启动前加一段清理逻辑,把旧容器和旧数据目录删掉,避免端口冲突和残留的 nodes.conf 干扰新集群。
4. 避坑排查:六个节点起不来或组不上集群的常见原因
4.1 容器起来了但集群创建卡住不动
现象:脚本执行到cluster create那一步长时间无输出,最后超时失败。原因通常是节点之间网络不通,最常见的是容器没挂在同一个自定义网络上,或者宿主机防火墙挡了集群总线端口。CentOS 7.x 默认开着 firewalld,17001 到 17006 这些总线端口如果没放行,节点之间 gossip 通信建立不起来。解决:确认所有容器docker inspect看到的 Network 是同一个,然后firewall-cmd --add-port=17001-17006/tcp --permanent放行后 reload。
4.2 cluster_state 一直是 fail
现象:cluster info返回cluster_state:fail,cluster_slots_assigned不是 16384。原因有两种,一种是槽位没分完,通常是cluster create过程中有节点掉线导致部分槽位没分配;另一种是某个主节点没有从节点且自身挂了,集群自动进入 fail 状态。解决:先cluster nodes看哪个节点是 fail 状态,如果是槽位问题,用redis-cli --cluster fix尝试修复,修不好就清掉所有节点的 nodes.conf 和 data 目录重新跑脚本。
4.3 密码设了但节点间认证失败
现象:集群创建时报NOAUTH Authentication required或者节点之间握手失败。原因是requirepass和masterauth两个参数必须同时设成一样的值,只设requirepass的话,主从复制时从节点拿不到密码,复制链路建不起来。解决:检查脚本里两个参数是否都传了,且值一致。另外redis-cli连接时要带-a参数,cluster create命令本身也要带-a。
4.4 重启宿主机后集群起不来
现象:机器重启后容器自动启动了,但集群状态是 fail。原因是容器启动顺序不确定,节点之间互相找不到,或者 nodes.conf 里记录的 IP 变了。Docker 容器重启后 IP 可能变化,如果 nodes.conf 里存的是旧 IP,节点就失联了。解决:给容器固定 IP 或者用容器名做节点地址,脚本里cluster meet用容器名而不是 IP。另外可以在容器启动命令里加--cluster-announce-ip指定对外通告的地址。
4.5 数据目录权限导致容器启动即退出
现象:docker ps -a看到容器状态是 Exited,docker logs显示 permission denied。原因是宿主机挂载目录/data/redis/的属主和容器内 redis 用户 UID 不匹配。Redis 官方镜像里 redis 用户 UID 通常是 999,宿主机目录如果归 root 且权限是 755,容器内写不进去。解决:chown -R 999:999 /data/redis/或者启动容器时加--user root,但后者不推荐,权限放开有安全风险。
5. 把这套脚本改造成可复用模板的几个手法
脚本跑通一次不难,难的是换台机器、换个端口段还能稳定跑起来。我一般会做三件事把它变成可复用模板。第一,把参数区抽成独立的cluster.conf文件,脚本开头source进来,这样不同环境用不同配置文件,脚本本体不动。第二,把sleep 5换成健康检查循环,用redis-cli ping轮询每个节点,全部返回 PONG 再执行组集群,比死等靠谱得多。第三,加一个cleanup函数,重建前先docker rm -f掉同名容器、删掉数据目录,避免残留状态干扰。
# 健康检查替代 sleep wait_for_redis() { local node=$1 local port=$2 local retries=30 while [ $retries -gt 0 ]; do if docker exec ${node} redis-cli -p ${port} ping 2>/dev/null | grep -q PONG; then return 0 fi retries=$((retries-1)) sleep 1 done echo "节点 ${node} 启动超时" return 1 }这个函数逐个节点确认就绪,比统一 sleep 更精确,节点多的时候也不会浪费时间。参数retries=30意味着最多等 30 秒,内网环境足够,如果机器负载高可以调到 60。
验证集群是否真正可用的终极方法,是模拟一个主节点挂掉,看从节点能不能自动顶上。docker stop redis-cluster-node-0之后等几秒,再cluster nodes看 node-3 是不是变成了 master,槽位有没有被接管。这个演练能暴露很多隐藏问题,比如从节点复制链路没建好、故障切换超时设置不合理。从那以后我每次部署完集群,都会强制走一遍主节点宕机演练,确认自动 failover 真的生效,而不是只看cluster info返回 ok 就放心。希望帮到你。
本文还有配套的精品资源,点击获取