Redis集群故障检测与自动故障转移
Redis集群通过Gossip协议检测故障,使用Raft变种协议实现自动故障转移,保障集群高可用。
故障检测机制
节点状态
Bash
PFAIL (Possible Failure):疑似下线,单节点视角
FAIL (Failure):确认下线,集群共识
检测流程
Bash
1. 节点A在cluster-node-timeout内未收到节点B响应
2. 节点A标记B为PFAIL
3. 节点A通过Gossip询问其他节点
4. 若多数主节点确认B为PFAIL/FAIL
5. 节点A标记B为FAIL
6. 广播FAIL消息到整个集群
配置参数
Bash
# 故障检测超时(毫秒)
cluster-node-timeout 5000
# 从节点有效因子
# 从节点断连时间 = cluster-node-timeout * replica-validity-factor
cluster-replica-validity-factor 10
# 故障转移超时
cluster-announce-timeout 3000
故障转移流程
主节点下线场景
Bash
1. 主节点M1被标记为FAIL
2. M1的从节点S1发起选举
3. S1获得多数主节点投票
4. S1晋升为新主节点
5. S1接管M1的槽位
6. 集群配置更新
选举过程详解
步骤1: 从节点准备
Bash
从节点检测到主节点FAIL
等待一小段时间(确保主节点真下线)
增加currentEpoch
发起选举请求
步骤2: 请求投票
Bash
# 从节点广播投票请求
CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST
# 消息内容
- currentEpoch: 当前纪元
- configEpoch: 配置纪元
- lastEpoch: 上次纪元
- 主节点ID
- 从节点ID
步骤3: 主节点投票
Bash
主节点投票条件:
1. 请求纪元 > 当前纪元
2. 从节点的主节点确实FAIL
3. 每个纪元只能投一票
4. 先到先得原则
步骤4: 获胜条件
Bash
需要获得:超过半数主节点的投票
投票数 >= (主节点数 / 2) + 1
Epoch纪元机制
Epoch类型
Bash
currentEpoch: 集群当前纪元,全局递增
configEpoch: 配置纪元,槽位分配版本
nodeEpoch: 节点纪元,节点状态版本
Epoch作用
text
1. 解决配置冲突
- 多个节点同时修改配置
- Epoch大的配置胜出
2. 选举协调
- 每个Epoch只能投一票
- 防止脑裂
3. 数据一致性
- 槽位迁移更新configEpoch
- 客户端缓存失效
Epoch更新时机
text
# 故障转移
新主节点晋升 → configEpoch++
# 槽位迁移
槽位分配变化 → configEpoch++
# 手动故障转移
CLUSTER FAILOVER → currentEpoch++
手动故障转移
安全转移(推荐)
text
# 从节点执行
CLUSTER FAILOVER
# 流程:
# 1. 从节点请求主节点停止写入
# 2. 主节点响应OK
# 3. 从节点同步完数据
# 4. 从节点发起选举
# 5. 成为新主节点
强制转移
text
# 主节点已下线时使用
CLUSTER FAILOVER FORCE
# 从节点直接发起选举
# 不等待主节点确认
接管转移
text
# 紧急情况使用
CLUSTER FAILOVER TAKEOVER
# 从节点直接晋升
# 不请求投票
# 可能导致数据不一致
转移对比
| 命令 | 主节点状态 | 数据安全 | 使用场景 |
|---|---|---|---|
| FAILOVER | 在线 | 安全 | 计划维护 |
| FAILOVER FORCE | 离线 | 安全 | 主节点故障 |
| FAILOVER TAKEOVER | 任意 | 风险 | 紧急恢复 |
从节点选举优先级
复制偏移量
text
从节点优先级由复制偏移量决定
偏移量大 = 数据新 = 优先级高
选举延迟
text
偏移量越大的从节点,选举延迟越小
delay = 500ms + random(0-500ms) + rank * 1000ms
rank: 从节点排名(按偏移量)
人工干预
text
# 设置从节点优先级
replica-priority 100 # 默认100,数字越小优先级越高
# 查看复制偏移量
INFO REPLICATION
# slave_repl_offset: 复制偏移量
故障恢复
主节点恢复
text
原主节点M1恢复后:
1. 发现已被标记为FAIL
2. 发现槽位已被新主节点接管
3. 转换为新主节点的从节点
4. 开始复制数据
查看集群状态
text
# 集群信息
CLUSTER INFO
# cluster_state: ok/fail
# cluster_slots_ok: 正常槽位数
# cluster_known_nodes: 节点数
# 节点详情
CLUSTER NODES
# flags: master/slave/fail/pfail
配置更新传播
更新机制
text
1. 新主节点晋升
2. 更新configEpoch
3. 广播更新消息
4. 其他节点更新配置
5. 客户端更新路由缓存
配置冲突解决
text
场景:网络分区导致多个主节点
解决:比较configEpoch
Epoch大的配置生效
监控与告警
关键指标
text
# 节点状态
CLUSTER NODES | grep fail
# 槽位状态
CLUSTER INFO | grep slots
# 复制延迟
INFO REPLICATION | grep lag
告警规则
text
1. 主节点FAIL状态持续 > 30秒
2. 从节点复制延迟 > 10秒
3. 集群状态为fail
4. 槽位未全覆盖
要点总结
- 故障状态:PFAIL(疑似) → FAIL(确认),需多数主节点同意
- 选举需要超过半数主节点投票才能成功
- Epoch机制解决配置冲突,Epoch大的配置胜出
- 手动故障转移优先使用CLUSTER FAILOVER,安全可靠
- cluster-node-timeout影响故障检测速度,网络差时需调大
- 从节点优先级由复制偏移量和replica-priority决定
- 配置cluster-replica-validity-factor控制从节点有效性
📝 发现内容有误?点击此处直接编辑