灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL

  • Redis

    • Redis 运维知识地图:从单机到 Cluster 排障
    • Redis 常用查询操作:五种数据类型速查 + 生产环境避坑
    • Redis 集群部署
    • Redis 大 key 分析:三条排查路径怎么选
    • Redis手动进行主从切换
      • 前言
      • 为什么需要手动 failover
        • 原理:Redis Cluster 故障转移机制
      • 验证切换成功
        • 完整验证脚本
        • 自动化健康检查命令
      • 坑与边界
      • 可复用要点
    • Redis集群添加节点之后数据重新均匀分配
    • Redis槽位slot解读
    • Redis Cluster 新增节点 slot 迁移卡住:"open slots" 故障复盘
    • Redis集群的创建、剔除节点与新增节点操作过程
    • Redis配置文件解读
    • redis cluster压测
    • Redis 慢查询告警与抓包分析排障脚本
    • Redis 的可用内存过高时的自动驱逐 key 策略详解
  • 高性能KV

  • TiDB

  • Elasticsearch

  • 数据管道

  • 其他数据库

  • 数据库
  • Redis
灯下哥谭
2022-03-17
目录

Redis手动进行主从切换

# Redis手动进行主从切换

# 前言

当redis集群中的一个节点出现故障,需要将主从互换的时候会用到

版本说明

本文写于 2022-03。
主从切换命令(SLAVEOF/REPLICAOF)与流程未变,经 2026-07 复核仍适用。

[dba@redisnode0001 bin]# sudo ./redis-cli -h <PUBLIC_IP> -p 8001 -c -a xxxxxxxxxxx --cluster check 127.0.0
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
<PUBLIC_IP>:9001 (c1422bc2...) -> 1 keys | 5461 slots | 1 slaves.
<PUBLIC_IP>:9002 (87f4cf99...) -> 0 keys | 5462 slots | 1 slaves.
<PUBLIC_IP>:9003 (63395075...) -> 1 keys | 5461 slots | 1 slaves.
[OK] 2 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node <PUBLIC_IP>:9001)
M: c1422bc23f702c702a1de872f5a0026238268fa9 <PUBLIC_IP>:9001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: c1000a4985fd5a8c8afd9c8bdaa4d99f137e78eb <PUBLIC_IP>:9003
   slots: (0 slots) slave
   replicates 633950751a8fc0a18b4a1ad4c5dd90095d4147b0
M: 87f4cf99d533f74532d5b586bbdeabe7dc0df499 <PUBLIC_IP>:9002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 633950751a8fc0a18b4a1ad4c5dd90095d4147b0 <PUBLIC_IP>:9003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 0ca6df3fb57b53700bb2d328696932d3f3fe62c9 <PUBLIC_IP>:9001
   slots: (0 slots) slave
   replicates c1422bc23f702c702a1de872f5a0026238268fa9
S: d6f6aa0a5003a25060e48032544f27044d5445ef <PUBLIC_IP>:9002
   slots: (0 slots) slave
   replicates 87f4cf99d533f74532d5b586bbdeabe7dc0df499
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

通过check 命令找到与主节点相同ID的从节点,连接上从节点之后执行命令

[dba@redisnode0001 bin]# sudo ./redis-cli -h <PUBLIC_IP> -p 9001 -c -a xxxxxxxxxxxxx 
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
<PUBLIC_IP>:9001> cluster failover
OK
<PUBLIC_IP>:9001> cluster nodes
87f4cf99d533f74532d5b586bbdeabe7dc0df499 <PUBLIC_IP>:9002@19002 master - 0 1638603378000 2 connected 5461-10922
633950751a8fc0a18b4a1ad4c5dd90095d4147b0 <PUBLIC_IP>:9003@19003 master - 0 1638603377000 3 connected 10923-16383
0ca6df3fb57b53700bb2d328696932d3f3fe62c9 <PUBLIC_IP>:9001@19001 myself,master - 0 1638603377000 5 connected 0-5460
c1422bc23f702c702a1de872f5a0026238268fa9 <PUBLIC_IP>:9001@19001 slave 0ca6df3fb57b53700bb2d328696932d3f3fe62c9 0 1638603378554 5 connected
d6f6aa0a5003a25060e48032544f27044d5445ef <PUBLIC_IP>:9002@19002 slave 87f4cf99d533f74532d5b586bbdeabe7dc0df499 0 1638603378000 2 connected
c1000a4985fd5a8c8afd9c8bdaa4d99f137e78eb <PUBLIC_IP>:9003@19003 slave 633950751a8fc0a18b4a1ad4c5dd90095d4147b0 0 1638603378752 3 connected
1
2
3
4
5
6
7
8
9
10
11

若无意在主节点上执行的话,会有以下报错

<PUBLIC_IP>:8001> cluster failover
(error) ERR You should send CLUSTER FAILOVER to a replica
1
2

# 为什么需要手动 failover

Redis Cluster 的故障转移默认是自动的:当主节点被判定为 fail(cluster-node-timeout 内无响应,且多数主节点认可),其从节点会自动提升为主节点。

手动 failover 的场景:

  • 计划内维护:需要重启主节点所在的机器,手动 failover 可以把影响降到毫秒级(自动 failover 需要等 cluster-node-timeout)。
  • 主节点性能异常:CPU/网络抖动但不至于被判定为 fail,手动切换让从节点接管。
  • 机架迁移:把主节点集中到特定机架,需要通过 failover 重新分配主从分布。
  • 硬件更换:更换主板、内存、磁盘等需要停机的操作,提前把业务切换到从节点。
  • 版本升级:Redis 升级通常需要重启,手动 failover 实现平滑升级。

与自动 failover 的区别:手动 failover 是强制且立即的,不需要等超时,也不需要多数主节点认可——它假设你确认当前主节点需要被替换。

# 原理:Redis Cluster 故障转移机制

Redis Cluster 的故障转移分为自动和手动两种,它们的底层机制有显著差异:

自动 failover 流程:

  1. 主节点被标记为 fail:至少需要多数主节点(N/2+1)在 cluster-node-timeout 时间内确认该节点不可达。
  2. 从节点发起选举:所有从节点中,复制偏移量最大的从节点获得优先选举权。
  3. 广播选举结果:获胜的从节点向集群所有节点广播 PONG,声明自己成为新的主节点。
  4. 槽位迁移:原主节点的槽位全部迁移到新主节点。

手动 failover(CLUSTER FAILOVER)流程:

  1. 从节点向主节点发送 CLUSTER FAILOVER 命令。
  2. 主节点阻塞当前复制流,将当前的复制偏移量发送给从节点。
  3. 从节点等待接收主节点的复制流,直到与主节点复制进度对齐。
  4. 从节点宣布自己为新的主节点,并广播更新后的集群配置。
  5. 原主节点降级为从节点,开始复制新的主节点。

# 验证切换成功

执行 cluster failover 后,立即验证:

redis-cli -h <target-node> -p <port> cluster nodes
1

判读要点:

  1. 原从节点:myself,master 表示它已提升为主节点,且最后一列显示槽位范围(如 0-5460)。
  2. 原主节点:显示为 slave,且 replicates 指向新的主节点 node-id。
  3. cluster_state:cluster info | grep cluster_state 应返回 ok。

# 完整验证脚本

#!/bin/bash
# 验证 Redis Cluster 主从切换是否成功

CLUSTER_HOST="127.0.0.1"
CLUSTER_PORT=9001

echo "=== 1. 检查集群状态 ==="
redis-cli -h $CLUSTER_HOST -p $CLUSTER_PORT cluster info | grep cluster_state

echo -e "\n=== 2. 检查所有节点角色 ==="
redis-cli -h $CLUSTER_HOST -p $CLUSTER_PORT cluster nodes | \
    awk '{print $1, $2, $3, $4, $NF}'

echo -e "\n=== 3. 检查槽位覆盖 ==="
redis-cli -h $CLUSTER_HOST -p $CLUSTER_PORT cluster info | grep cluster_slots_ok

echo -e "\n=== 4. 模拟业务写入测试 ==="
redis-cli -h $CLUSTER_HOST -p $CLUSTER_PORT -c set test_key_$(date +%s) verification_value
redis-cli -h $CLUSTER_HOST -p $CLUSTER_PORT -c get test_key_*
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 自动化健康检查命令

# 一键检查集群健康状态
redis-cli --cluster check <HOST>:<PORT> 2>&1 | grep -E "(OK|All nodes|WARNING|FAIL)"

# 检查所有主节点的槽位是否都有从节点接管
redis-cli -h <HOST> -p <PORT> cluster nodes | grep -v "slave" | grep "master" | wc -l

# 检查每个主节点是否至少有一个健康的从节点
redis-cli -h <HOST> -p <PORT> cluster nodes | grep "slave" | grep -v "fail" | wc -l
1
2
3
4
5
6
7
8

# 坑与边界

  1. 脑裂风险:手动 failover 期间,如果原主节点仍在写数据(比如你只断了它的集群总线但没停客户端连接),会导致双主局面——两边都有最新数据,但复制方向已切换,数据会分歧。执行 failover 前务必确认原主节点已停止接受写请求(CLIENT PAUSE 或直接停服)。

    防御措施:

    # 在原主节点上暂停所有客户端写入
    redis-cli -h <old-master> -p 8001 CLIENT PAUSE 30000 WRITE
    
    # 确认暂停成功
    redis-cli -h <old-master> -p 8001 CLIENT LIST | grep flags
    # 应该看到 'N' (normal) 仍然存在,但写入已阻塞
    
    1
    2
    3
    4
    5
    6
  2. 自动提升的竞态:如果手动 failover 执行时,自动故障转移也在进行(比如原主节点刚好超时),可能导致 failover 失败或产生意外的拓扑。建议在业务低峰期执行,并提前把 cluster-node-timeout 临时调大(执行完再调回)。

    # 临时调大超时时间(生产环境慎用)
    CONFIG SET cluster-node-timeout 30000
    
    # 执行完手动 failover 后恢复
    CONFIG SET cluster-node-timeout 15000
    
    1
    2
    3
    4
    5
  3. 从节点复制延迟:如果从节点落后主节点太多(master_repl_offset 差距大),failover 后这部分未复制的数据会丢失。执行前先检查偏移量:

    # 在从节点上检查复制延迟
    redis-cli info replication | grep -E "master_link_status|master_repl_offset|slave_read_repl_offset"
    
    # 在主节点上检查当前偏移量
    redis-cli info replication | grep master_repl_offset
    
    1
    2
    3
    4
    5
  4. 客户端重定向:failover 完成后,客户端需要收到 MOVED 重定向才能正确路由。大多数 Redis 客户端会自动跟随,但部分老旧客户端可能需要重建连接。建议在切换后监控客户端日志,确认没有大量 MOVED 错误。

  5. failover 不是回滚操作:一旦执行,原主节点变成从节点,数据流向反转。如果你想恢复原来的主从关系,需要在新主节点上再执行一次 cluster failover(它现在是主节点,需要先 cluster failover TAKEOVER 强制夺回主权——但这会丢失新主节点上的写入)。

  6. 权限要求:执行 failover 的从节点必须能与多数主节点通信,否则无法完成选举。如果集群正处于分区状态(网络分裂),failover 会报错。

  7. 数据丢失场景:手动 failover 在以下场景会导致数据丢失:

    • 从节点复制缓冲已满(client-output-buffer-limit replica 配置过小)
    • 网络分区期间客户端仍写入原主节点
    • 从节点接收复制流前被强制提升
  8. 执行频率限制:Redis Cluster 不建议频繁执行手动 failover,每次切换都会触发槽位迁移和客户端重定向,频繁切换会导致:

    • 客户端频繁收到 MOVED 重定向
    • 集群拓扑频繁变化,增加网络开销
    • 复制延迟累积

# 可复用要点

  1. 手动 failover 最适合计划内维护场景:相比自动 failover 需要等待 cluster-node-timeout 才能触发,手动 failover 可以做到毫秒级切换,业务感知几乎为零。

  2. failover 前必做三件事:

    • 确认从节点与主节点的复制延迟在可接受范围(master_repl_offset 差值 < 1000)
    • 暂停原主节点的写入(CLIENT PAUSE 或关闭客户端连接)
    • 记录切换前的完整拓扑(cluster nodes 输出)
  3. 切换后的验证清单:

    • cluster_state 必须为 ok
    • 所有 16384 个槽位都有明确归属
    • 每个主节点都有健康的从节点
    • 客户端可以正常写入和读取
  4. 回滚方案:如果切换后发现问题,需要在新主节点上再次执行 cluster failover TAKEOVER 强制夺回主权,但会丢失切换期间新主节点的写入数据。

  5. 监控告警建议:在执行手动 failover 时,建议同时监控以下指标:

    • cluster_cluster_slots_assigned:16384 表示所有槽位已分配
    • cluster_cluster_slots_ok:每个主节点槽位状态健康
    • replication_master_repl_offset:主从复制进度对比
#高可用#Redis
上次更新: 9/11/2026

← Redis 大 key 分析:三条排查路径怎么选 Redis集群添加节点之后数据重新均匀分配→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式