跳到正文

Redis 集群生命周期管理 ​

一句话:集群生命周期管理把「有哪些集群、谁在用、拓扑是什么、能不能改」从个人经验变成可查询、可对账、可审计的流程;它换来变更前的可见性和失败后的可回滚,代价是平台里的拓扑永远只是缓存,真实状态必须以 Redis 为准。

适用版本:Redis 7.x / 8.x。集群原理见 08-集群模式,指标口径见 15-Redis监控指标与告警;本篇只讨论平台化运维。

为什么需要 ​

集群少的时候,拓扑记在运维脑子里、密码放在脚本里、扩容靠人敲命令,还能转。集群一多,问题会变成四类:

  • 凭据分散:同一个集群的密码出现在配置、脚本、告警和某个人本地,轮换或人员变动时收不回来。
  • 拓扑失真:节点加过、槽迁过、主从切过,文档没更新;故障时按旧拓扑找人,找到的是已经下线的节点。
  • 变更靠手工:加节点、迁槽、下线各有一套命令,先做什么后做什么没有固定顺序,失败后也不知道回到哪一步。
  • 影响面不清:一个集群挂了,不知道哪些应用在用、负责人是谁、能不能先降级。

平台的价值不是「把命令包一层按钮」,而是把集群、节点、应用三者关联起来,让每次变更都有前置检查、速率限制、回滚点和审计记录。

核心机制 ​

元数据模型:三层,且以 Redis 为准 ​

层关键字段用途
集群逻辑名、环境、机房、版本、拓扑类型定位和分组,避免用 IP 当身份
节点地址、角色、slot 范围、状态、复制偏移描述当前拓扑和故障位置
应用应用名、负责人、依赖的逻辑集群回答「切这个集群会影响谁」

平台库只存两类东西:低频变化的归属信息,以及最近一次采集到的拓扑快照。归属信息由人维护,拓扑快照由采集覆盖;两者冲突时,拓扑字段以 Redis 返回为准,归属字段以资产系统为准。示例命名可用 RedisClusterRegistry 管接入,用 LogicalCluster 表示逻辑集群,避免把 IP 写进应用配置。

接入与发现 ​

接入从一个可用的种子地址开始,而不是从一份手工节点清单开始:

  1. 用最小权限的专用账号连接种子节点,先按配置完成 AUTH 并做 PING,再用 INFO server 看版本、用 CLUSTER INFO 确认 cluster_enabled:1。
  2. 继续用 CLUSTER INFO 确认 cluster_state:ok、槽已分配;再执行 CLUSTER NODES 拉取全量节点。
  3. 解析每行的节点 ID、ip:port@cport 地址、角色标记、主节点 ID、连接状态和 slot 范围;myself 标记当前连接的是哪个节点。
  4. 用返回的节点逐一复连,校验版本、密码和集群总线端口可达性,避免只信任一个节点的视角。
  5. 密码加密后入库,界面和日志只显示掩码;查询类操作和变更类操作使用不同权限的账号。

地址解析要特别小心:CLUSTER NODES 可能返回主机名、IPv6 或 NAT 后的地址,云上还可能出现 cluster-announce-* 配错导致节点互相不可达。接入校验不通过时,宁可标记为「待确认」,不要把半套拓扑写进缓存。

健康与状态机 ​

平台状态不能只由 PING 决定。至少要一起看:cluster_state、16384 个 slot 是否全覆盖、cluster_slots_pfail / cluster_slots_fail、主从对应关系、复制偏移差,以及本次采集本身是否成功。

这张状态机把「平台看不见」和「集群真的坏了」分开:认证失败、连接超时、采集任务自身异常,都先落到 UNKNOWN,而不是直接报 CRITICAL。只有采集成功且检查项不通过,才进入 DEGRADED 或 CRITICAL;否则一次网络抖动就会制造大量误报。

变更操作 ​

操作前置检查限速与回滚点主要风险
加节点版本和配置一致、总线端口可达、节点为空、目标容量足够一次加一个,观察心跳和延迟;分配 slot 前可用 del-node 撤销新节点配置漂移,加入后拖慢心跳
迁移 slot目标内存和 CPU 有余量、大 key 已盘点、客户端支持重定向分批迁移,按延迟暂停;SETSLOT NODE 前可反向迁回大 key 阻塞、迁移期间延迟上升、客户端不处理 ASK
主从切换副本在线、偏移接近、多数主节点存活一次只切一个分片;记录原主,异常时可反向 failover强制 takeover 可能丢掉未复制的写
下线节点不持有 slot、无业务连接、副本关系已解除先摘流量观察,再删副本和主;删除只能重新加入,不能原地撤销被 forget 的节点可能通过 Gossip 重新加入

迁移期间客户端会看到 MOVED / ASK,延迟上升是预期代价,不是故障。真正不可逆的点是 slot 归属切换并开始接收新写入之后:此时「回滚」不再是撤销,而是反向迁移,必须重新评估数据差异。命令细节见 08-集群模式,平台层不要再封装一套自己的迁移协议。

定时对账 ​

对账任务做三件事:重新采集真实拓扑、与平台快照逐字段比较、把差异变成事件。

  • 节点消失或新增:标记快照过期并告警,保留历史,不直接删除记录。
  • IP 或主机名变化:先确认是迁移、NAT 还是配置错误,再更新展示;不要自动改应用配置。
  • 版本漂移:记录版本变化,跨出支持范围时告警,避免用旧客户端的假设操作新集群。
  • slot 或角色变化:更新快照用于展示,同时生成变更事件;是否触发后续动作由人确认。

对账失败和对账发现差异是两件事:前者是平台采集不到,后者是真实拓扑变了。两者都要告警,但前者不能按集群故障处理。平台默认只读对账,不自动改拓扑;自动修复最多做到刷新缓存和重新采集,不能自动迁槽或切主。

最小上手 ​

以下命令在 Redis 7.x、能访问集群总线端口的环境执行。用环境变量传密码,避免密码进入 shell 历史和进程列表。

bash
export REDISCLI_AUTH='<password>'

# 1. 官方检查:槽覆盖、节点角色、副本关系
redis-cli -h 10.0.0.1 -p 6379 --no-auth-warning \
  --cluster check 10.0.0.1:6379

# 2. 拉取拓扑并按角色、slot 汇总
redis-cli -h 10.0.0.1 -p 6379 --no-auth-warning CLUSTER NODES |
awk '{
  addr=$2; sub(/@.*/, "", addr);
  role=($3 ~ /master/) ? "master" : "replica";
  slots=""; for (i=9; i<=NF; i++) slots=slots " " $i;
  printf "%-22s %-8s%s\n", addr, role, slots
}' | sort

两条命令的关键输出合在一起类似(地址和节点 ID 会不同):

text
10.0.0.1:6379          master   0-5460
10.0.0.2:6379          master   5461-10922
10.0.0.3:6379          master   10923-16383
10.0.0.11:6379         replica
10.0.0.12:6379         replica
10.0.0.13:6379         replica
[OK] All 16384 slots covered.

判断依据:三个主节点覆盖 0-16383 且没有空洞,副本行没有 slot,--cluster check 最后输出 [OK] All 16384 slots covered.。如果检查提示有 slot 没有被覆盖,先查 slot 归属和迁移状态,不要直接重启节点。

生产动作 ​

  • 审计字段固定:操作人、复核人、目标集群、命令参数、前置检查结果、开始/结束时间、回滚点、执行结果。缺少任何一项,事后无法还原。
  • 双人复核:生产环境的迁槽、切主、下线必须两人确认;查看和变更使用不同权限,变更账号不常驻。
  • 变更窗口:迁槽和切主避开业务高峰;窗口内冻结同集群的其他变更,避免两个操作互相覆盖回滚点。
  • 迁移速率:用 redis-cli --cluster reshard 的 --cluster-pipeline 控制批量,观察 P99、latest_fork_usec 和 connected_clients;超过基线就暂停,不要为了赶窗口加速。
  • 容量水位:内存使用率 75% 预警、85% 启动扩容(经验起点,按业务基线校准)。扩容要留出迁移和副本缓冲的空间,不能等 maxmemory 顶满才动手。
  • 失败处理:回滚点之前按预案回滚;回滚点之后停止操作、保留现场、升级处理,不要连着执行相反命令。
  • 平台故障:平台不可用时数据面继续运行;值班先用 redis-cli 和现有 runbook 处置,不要把平台恢复当成恢复业务的前置条件。

参数上,cluster-node-timeout=15000(Redis 7.x 默认)决定主观下线判定,调小切换快但误判多;cluster-require-full-coverage=yes 默认要求全槽可用,设为 no 会牺牲部分 key 的可用性换整体可写。平台应该展示这些值,但不要替用户静默修改。

边界 ​

平台解决的是「看得见、改得稳、查得到」,不解决 Redis 自身的高可用。主节点故障后的选主、槽接管仍然由 Cluster 的 Gossip 和多数派完成;平台宕机不影响数据面,也不应该被放进请求链路。

几条硬边界:

  • 不暴露任意命令:只开放白名单内的管理命令和只读查询,禁止 FLUSHALL、CONFIG SET、任意 EVAL 这类高杀伤操作;管理员通道也要审计。
  • 自动修复限范围:自动刷新元数据可以,自动迁槽、自动切主、自动改应用配置不可以;这些动作的代价不可逆。
  • 跨版本和跨云有差异:托管 Redis 可能禁用 CLUSTER 管理命令、隐藏总线端口或使用私有地址;纳管前先在目标环境验证命令可用性。
  • 缓存会过期:平台展示的拓扑有采集间隔,故障定位时以现场 CLUSTER NODES / CLUSTER INFO 为准,不能拿缓存当证据。
  • 小规模未必需要平台:几个集群、固定负责人、变更频率低时,一份准确的资产表和标准 runbook 可能更便宜;平台的成本包括开发、权限和长期维护。

讲清楚 ​

集群生命周期管理要解决的是集群多起来之后,凭据、拓扑、变更和影响面同时失控,而不是把命令包成按钮。平台把集群、节点、应用建成三层元数据,用 CLUSTER NODES 和 CLUSTER INFO 采集拓扑,但平台库只是缓存,冲突时以 Redis 为准;健康状态还要区分「采集失败」和「集群故障」。迁槽、切主、下线都要有前置检查、限速和回滚点,slot 一旦接收新写入,回滚就变成反向迁移。平台不能替代 Redis 自身的选主与故障转移,也不应拥有直接改拓扑的权限。

相关:06-主从复制、07-哨兵模式、08-集群模式、15-Redis监控指标与告警、99-生产检查清单。

把一门技术讲透到既懂也会用