资讯动态

Docker一键部署Redis三主三从集群Shell脚本实战

发布时间:2026/10/16 3:24:41 来源:尧图企业网站定制
简介这份资源面向需要在 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 对应 170017002 对应 17002以此类推。集群总线端口用于节点间 gossip 通信少了它节点永远握不上手。Docker 网络这块有个容易忽略的点六个容器必须挂在同一个自定义 bridge 网络上不能用默认的 bridge。默认 bridge 不支持容器名 DNS 解析脚本里如果用容器名做cluster meet会直接失败。自定义网络下容器之间可以用服务名互相访问脚本内部做节点发现时就不用硬编码 IP换台机器也不用改配置。2.2 脚本的核心执行流程拆解下面这段是脚本主干逻辑的简化版保留了关键步骤和参数去掉了日志着色和错误重试的装饰代码。你可以把它理解成脚本的「骨架」实际脚本会在每个步骤前后加上状态检查和输出。#!/bin/bash # redis-cluster-deploy.sh # 适用 CentOS 7.x需提前安装 docker-ce # 参数区按需修改 REDIS_IMAGEredis:6.2 CLUSTER_NAMEredis-cluster NETWORK_NAMEredis-net BASE_PORT7001 NODE_COUNT6 PASSWORDyour_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是不是okcluster_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 默认开着 firewalld17001 到 17006 这些总线端口如果没放行节点之间 gossip 通信建立不起来。解决确认所有容器docker inspect看到的 Network 是同一个然后firewall-cmd --add-port17001-17006/tcp --permanent放行后 reload。4.2 cluster_state 一直是 fail现象cluster info返回cluster_state:failcluster_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看到容器状态是 Exiteddocker 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 retries30 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 更精确节点多的时候也不会浪费时间。参数retries30意味着最多等 30 秒内网环境足够如果机器负载高可以调到 60。验证集群是否真正可用的终极方法是模拟一个主节点挂掉看从节点能不能自动顶上。docker stop redis-cluster-node-0之后等几秒再cluster nodes看 node-3 是不是变成了 master槽位有没有被接管。这个演练能暴露很多隐藏问题比如从节点复制链路没建好、故障切换超时设置不合理。从那以后我每次部署完集群都会强制走一遍主节点宕机演练确认自动 failover 真的生效而不是只看cluster info返回 ok 就放心。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑