主题
Redis 集群生命周期管理
一句话:集群生命周期管理把「有哪些集群、谁在用、拓扑是什么、能不能改」从个人经验变成可查询、可对账、可审计的流程;它换来变更前的可见性和失败后的可回滚,代价是平台里的拓扑永远只是缓存,真实状态必须以 Redis 为准。
适用版本:Redis 7.x / 8.x。集群原理见 08-集群模式,指标口径见 15-Redis监控指标与告警;本篇只讨论平台化运维。
为什么需要
集群少的时候,拓扑记在运维脑子里、密码放在脚本里、扩容靠人敲命令,还能转。集群一多,问题会变成四类:
- 凭据分散:同一个集群的密码出现在配置、脚本、告警和某个人本地,轮换或人员变动时收不回来。
- 拓扑失真:节点加过、槽迁过、主从切过,文档没更新;故障时按旧拓扑找人,找到的是已经下线的节点。
- 变更靠手工:加节点、迁槽、下线各有一套命令,先做什么后做什么没有固定顺序,失败后也不知道回到哪一步。
- 影响面不清:一个集群挂了,不知道哪些应用在用、负责人是谁、能不能先降级。
平台的价值不是「把命令包一层按钮」,而是把集群、节点、应用三者关联起来,让每次变更都有前置检查、速率限制、回滚点和审计记录。
核心机制
元数据模型:三层,且以 Redis 为准
| 层 | 关键字段 | 用途 |
|---|---|---|
| 集群 | 逻辑名、环境、机房、版本、拓扑类型 | 定位和分组,避免用 IP 当身份 |
| 节点 | 地址、角色、slot 范围、状态、复制偏移 | 描述当前拓扑和故障位置 |
| 应用 | 应用名、负责人、依赖的逻辑集群 | 回答「切这个集群会影响谁」 |
平台库只存两类东西:低频变化的归属信息,以及最近一次采集到的拓扑快照。归属信息由人维护,拓扑快照由采集覆盖;两者冲突时,拓扑字段以 Redis 返回为准,归属字段以资产系统为准。示例命名可用 RedisClusterRegistry 管接入,用 LogicalCluster 表示逻辑集群,避免把 IP 写进应用配置。
接入与发现
接入从一个可用的种子地址开始,而不是从一份手工节点清单开始:
- 用最小权限的专用账号连接种子节点,先按配置完成
AUTH并做PING,再用INFO server看版本、用CLUSTER INFO确认cluster_enabled:1。 - 继续用
CLUSTER INFO确认cluster_state:ok、槽已分配;再执行CLUSTER NODES拉取全量节点。 - 解析每行的节点 ID、
ip:port@cport地址、角色标记、主节点 ID、连接状态和 slot 范围;myself标记当前连接的是哪个节点。 - 用返回的节点逐一复连,校验版本、密码和集群总线端口可达性,避免只信任一个节点的视角。
- 密码加密后入库,界面和日志只显示掩码;查询类操作和变更类操作使用不同权限的账号。
地址解析要特别小心: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 自身的选主与故障转移,也不应拥有直接改拓扑的权限。