Skip to content

Redis 自动故障转移

在生产环境中,Redis 服务的高可用性至关重要。单点 Redis 实例存在以下风险:

  • 单点故障:单个实例故障会导致整个服务不可用
  • 维护窗口:主节点维护时需要手动切换,导致服务中断
  • 数据丢失风险:单点故障可能导致未持久化数据丢失

Redis 自动故障转移是保障 Redis 服务高可用性的关键机制,能够在主节点发生故障时自动将从节点提升为主节点,确保业务连续性。其主要目标是:

  • 快速检测故障:及时发现主节点故障
  • 自动切换:无需人工干预,自动将从节点提升为主节点
  • 数据一致性:确保故障转移过程中数据一致性
  • 业务连续性:最小化服务中断时间
  • 可扩展性:支持大规模 Redis 集群

Redis 提供两种自动故障转移实现方式:

  • Redis Sentinel:适用于主从架构,提供监控、通知和自动故障转移功能
  • Redis Cluster:适用于分布式集群架构,内置故障检测和自动故障转移功能

Redis Sentinel 自动故障转移

1. Sentinel 架构

Redis Sentinel 是一个分布式系统,用于监控 Redis 主从架构,提供自动故障转移功能。

1.1 Sentinel 组件

  • Sentinel 节点:监控 Redis 主从实例,执行故障检测和故障转移
  • Redis 主节点:处理客户端写入请求
  • Redis 从节点:复制主节点数据,在主节点故障时可被提升为主节点
  • 客户端:通过 Sentinel 获取当前主节点信息,实现高可用连接

1.2 Sentinel 部署建议

  • 至少 3 个 Sentinel 节点:确保 Sentinel 自身的高可用性
  • 奇数个 Sentinel 节点:避免脑裂问题
  • 分布在不同物理机器:避免单点故障
  • 与 Redis 实例独立部署:确保 Sentinel 不会受 Redis 实例故障影响

2. Sentinel 故障检测

Sentinel 采用多层故障检测机制,确保准确检测主节点故障。

2.1 主观下线(SDOWN)

单个 Sentinel 节点认为主节点不可用:

  • PING 命令检测:Sentinel 定期向主节点发送 PING 命令
  • 响应超时:如果主节点在 down-after-milliseconds 时间内未响应,Sentinel 标记主节点为主观下线
  • 主观下线条件:主节点返回无效响应或无响应

2.2 客观下线(ODOWN)

多个 Sentinel 节点一致认为主节点不可用:

  • 投票机制:Sentinel 向其他 Sentinel 节点询问主节点状态
  • 法定人数:当同意主节点下线的 Sentinel 节点数达到 quorum 配置值时,主节点被标记为客观下线
  • 故障确认:只有客观下线的主节点才会触发故障转移

3. Sentinel 故障转移流程

当主节点被标记为客观下线后,Sentinel 开始执行故障转移流程:

3.1 选举 Sentinel 领导者

  • Raft 算法:Sentinel 节点通过 Raft 算法选举出一个领导者
  • 领导者职责:只有领导者才能执行故障转移操作
  • 选举条件:获得多数 Sentinel 节点支持的 Sentinel 成为领导者

3.2 选择最优从节点

Sentinel 领导者选择最优从节点提升为主节点,选择标准包括:

  1. 健康状态:从节点必须处于在线状态
  2. 复制偏移量:选择复制偏移量最大的从节点(数据最完整)
  3. 优先级:选择 slave-priority 配置值最高的从节点
  4. 运行时间:选择运行时间最长的从节点
  5. 进程 ID:选择进程 ID 最小的从节点(作为最后选择标准)

3.3 执行故障转移

故障转移的具体步骤:

  1. 提升从节点为主节点:Sentinel 向选中的从节点发送 SLAVEOF NO ONE 命令,将其提升为主节点
  2. 更新其他从节点:Sentinel 向其他从节点发送 SLAVEOF <new-master-ip> <new-master-port> 命令,让它们复制新的主节点
  3. 更新主节点信息:Sentinel 更新内部记录的主节点信息
  4. 通知客户端:Sentinel 向客户端发布主节点变更通知
  5. 旧主节点恢复处理:当旧主节点恢复时,Sentinel 将其转换为新主节点的从节点

4. Sentinel 配置优化

4.1 核心配置参数

txt
# redis-sentinel.conf

# 监控的主节点信息
# <master-name> <ip> <port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2

# 主节点主观下线时间(毫秒)
sentinel down-after-milliseconds mymaster 30000

# 故障转移超时时间(毫秒)
sentinel failover-timeout mymaster 180000

# 同时进行故障转移的从节点数量
sentinel parallel-syncs mymaster 1

# 从节点优先级
sentinel slave-priority mymaster 100

# 启用脚本通知
sentinel notification-script mymaster /path/to/notification-script.sh

# 启用故障转移后脚本
sentinel client-reconfig-script mymaster /path/to/client-reconfig-script.sh

4.2 配置优化建议

  • down-after-milliseconds:根据网络环境调整,建议 10000-30000 毫秒
  • quorum:建议设置为 Sentinel 节点数的一半加 1(例如 3 个 Sentinel 节点,quorum 设为 2)
  • parallel-syncs:根据从节点数量调整,建议设置为 1 或 2,避免同时复制导致网络拥塞
  • failover-timeout:建议设置为 180000-360000 毫秒
  • slave-priority:根据从节点性能设置不同优先级

5. Sentinel 监控与告警

5.1 监控指标

  • Sentinel 状态sentinel master <master-name>
  • 主从复制状态info replication
  • 故障转移次数sentinel stats
  • Sentinel 连接数info sentinel

5.2 告警配置

  • 主节点主观下线:当 Sentinel 检测到主节点主观下线时触发告警
  • 主节点客观下线:当主节点被标记为客观下线时触发告警
  • 故障转移开始:当开始执行故障转移时触发告警
  • 故障转移完成:当故障转移完成时触发告警
  • Sentinel 节点故障:当 Sentinel 节点故障时触发告警

Redis Cluster 自动故障转移

1. Cluster 架构

Redis Cluster 是一个分布式集群架构,将数据分片存储在多个节点上,内置故障检测和自动故障转移功能。

1.1 Cluster 组件

  • 主节点:负责处理槽位数据和客户端请求
  • 从节点:复制主节点数据,在主节点故障时可被提升为主节点
  • 槽位(Slot):Redis Cluster 将数据分为 16384 个槽位,每个主节点负责一部分槽位
  • Gossip 协议:用于节点间通信,交换节点状态信息

1.2 Cluster 部署建议

  • 至少 3 个主节点:确保 Cluster 可用性
  • 每个主节点至少 1 个从节点:提供故障转移能力
  • 分布在不同物理机器:避免单点故障
  • 合理分配槽位:确保槽位在主节点间均匀分布

2. Cluster 故障检测

Redis Cluster 使用 Gossip 协议进行故障检测:

2.1 节点间通信

  • PING/PONG 消息:节点定期向其他节点发送 PING 消息,接收节点返回 PONG 消息
  • 消息内容:包含节点状态、槽位信息、主从关系等
  • 通信频率:根据节点数量动态调整,默认每秒发送 10 个 PING 消息

2.2 故障检测流程

  1. 节点不可达:当节点 A 向节点 B 发送 PING 消息,在 cluster-node-timeout 时间内未收到 PONG 响应
  2. 标记疑似故障:节点 A 将节点 B 标记为 PFAIL(可能故障)
  3. 传播故障信息:节点 A 通过 Gossip 协议将节点 B 的 PFAIL 状态传播给其他节点
  4. 确认故障:当超过半数主节点将节点 B 标记为 PFAIL 时,节点 B 被标记为 FAIL(确认故障)
  5. 广播故障信息:将节点 B 的 FAIL 状态广播给所有节点

3. Cluster 故障转移流程

当主节点被标记为 FAIL 后,Cluster 开始执行故障转移流程:

3.1 从节点选举

  • 资格检查:从节点必须满足以下条件才能参与选举:
    • 与故障主节点的网络连接正常
    • 复制偏移量足够接近故障主节点
    • 最近一次与故障主节点通信的时间不超过 cluster-node-timeout * 2
  • 选举投票:从节点向其他主节点发送 FAILOVER_AUTH_REQUEST 消息请求投票
  • 获得多数票:当从节点获得超过半数主节点的投票时,成功当选
  • 选举限制:每个主节点在一个故障转移周期内只能投票一次

3.2 故障转移执行

  1. 提升从节点为主节点:当选的从节点执行 SLAVEOF NO ONE 命令,提升为主节点
  2. 接管槽位:新主节点接管原主节点负责的所有槽位
  3. 广播配置更新:新主节点向所有节点广播 PONG 消息,包含新的槽位配置
  4. 更新其他从节点:其他从节点开始复制新主节点
  5. 客户端重定向:客户端收到 MOVED 或 ASK 错误时,更新本地缓存的槽位映射

4. Cluster 配置优化

4.1 核心配置参数

txt
# redis.conf

# 启用 Cluster 模式
cluster-enabled yes

# Cluster 配置文件路径
cluster-config-file nodes-6379.conf

# Cluster 节点超时时间(毫秒)
cluster-node-timeout 15000

# 从节点选举超时时间(毫秒)
cluster-slave-validity-factor 10

# 从节点选举优先级
cluster-slave-priority 100

# 故障转移超时时间(毫秒)
cluster-migration-barrier 1

# 启用自动重分片
cluster-allow-reads-when-down no

4.2 配置优化建议

  • cluster-node-timeout:建议设置为 15000-30000 毫秒
  • cluster-slave-validity-factor:建议设置为 1-10,值越小,从节点越容易参与选举
  • cluster-slave-priority:根据从节点性能设置不同优先级
  • cluster-migration-barrier:建议设置为 1,确保每个主节点至少有一个从节点
  • cluster-allow-reads-when-down:建议设置为 no,避免在 Cluster 不可用时返回不一致数据

5. Cluster 监控与告警

5.1 监控指标

  • Cluster 状态cluster info
  • 节点状态cluster nodes
  • 槽位分布cluster slots
  • 主从关系info replication
  • 故障转移次数info stats | grep failover_count

5.2 告警配置

  • 节点故障:当节点被标记为 FAIL 时触发告警
  • 槽位不可用:当有槽位处于不可用状态时触发告警
  • 从节点数量不足:当主节点的从节点数量低于配置值时触发告警
  • 复制偏移量差异大:当从节点与主节点的复制偏移量差异超过阈值时触发告警
  • Cluster 不可用:当 Cluster 状态为 fail 时触发告警

Sentinel vs Cluster 自动故障转移对比

特性Redis SentinelRedis Cluster
适用架构主从架构分布式集群架构
故障检测机制主观下线 + 客观下线Gossip 协议 + PFAIL/FAIL
故障转移触发条件主节点客观下线主节点被标记为 FAIL
从节点选举方式Sentinel 领导者选择从节点选举 + 投票机制
故障转移时间秒级秒级
数据分片不支持支持(16384 个槽位)
水平扩展不支持支持
部署复杂度中等较高
适用场景中小规模 Redis 部署大规模 Redis 部署

自动故障转移最佳实践

1. 部署建议

  • Sentinel 部署

    • 至少 3 个 Sentinel 节点,分布在不同物理机器
    • 与 Redis 实例独立部署
    • 配置合理的 down-after-millisecondsquorum 参数
  • Cluster 部署

    • 至少 3 个主节点,每个主节点至少 1 个从节点
    • 分布在不同物理机器
    • 合理分配槽位,确保均匀分布
    • 配置合理的 cluster-node-timeout 参数

2. 配置优化

  • 故障检测参数:根据网络环境和业务需求调整故障检测超时时间
  • 从节点优先级:根据从节点性能设置不同优先级,确保最优从节点被提升为主节点
  • 并行复制数量:Sentinel 中合理设置 parallel-syncs,避免同时复制导致网络拥塞
  • 选举限制:Cluster 中合理设置 cluster-slave-validity-factor,平衡故障转移速度和准确性

3. 监控与告警

  • 建立完善的监控体系:使用 Prometheus + Grafana 等监控工具监控自动故障转移相关指标
  • 设置合理的告警阈值:根据业务需求设置告警阈值,及时发现和处理问题
  • 监控故障转移过程:记录故障转移日志,分析故障转移原因和性能
  • 定期测试故障转移:模拟主节点故障,测试自动故障转移功能是否正常工作

4. 数据一致性保障

  • 合理配置持久化:启用 AOF 持久化,设置合适的 appendfsync 策略
  • 主从复制优化:配置 repl-diskless-sync yes 减少复制延迟
  • 避免写入放大:合理设置 repl-backlog-size,避免频繁全量复制
  • 监控复制偏移量:定期检查从节点与主节点的复制偏移量差异

5. 客户端适配

  • 使用支持高可用的客户端:选择支持 Sentinel 或 Cluster 的客户端库
  • 实现客户端重试机制:客户端在收到连接错误时,自动重试连接
  • 缓存主节点信息:客户端定期从 Sentinel 或 Cluster 获取最新的主节点信息
  • 处理 MOVED/ASK 错误:Cluster 客户端需要正确处理 MOVED 和 ASK 错误,更新槽位映射

常见问题(FAQ)

Q1: 如何选择 Redis Sentinel 和 Redis Cluster?

A1: 选择依据业务需求和规模:

  • Redis Sentinel:适用于中小规模 Redis 部署,主从架构,无需数据分片
  • Redis Cluster:适用于大规模 Redis 部署,需要数据分片和水平扩展

Q2: 如何优化 Redis Sentinel 故障转移速度?

A2: 优化 Sentinel 故障转移速度的方法:

  1. 减少 down-after-milliseconds:缩短主观下线检测时间
  2. 合理设置 quorum:确保快速达成客观下线共识
  3. 增加 Sentinel 节点数量:提高故障检测和决策速度
  4. 优化网络环境:减少节点间通信延迟
  5. 设置合理的 parallel-syncs:加快从节点复制速度

Q3: 如何优化 Redis Cluster 故障转移速度?

A3: 优化 Cluster 故障转移速度的方法:

  1. 减少 cluster-node-timeout:缩短故障检测时间
  2. 设置合适的 cluster-slave-validity-factor:加快从节点选举速度
  3. 增加从节点数量:提高故障转移成功率
  4. 优化网络环境:减少节点间通信延迟
  5. 确保从节点复制偏移量接近主节点:减少故障转移后的数据同步时间

Q4: 如何处理自动故障转移过程中的数据丢失问题?

A4: 处理数据丢失问题的方法:

  1. 启用 AOF 持久化:设置 appendfsync everysecappendfsync always
  2. 配置 min-slaves-to-write:确保主节点至少有 N 个从节点处于正常复制状态才允许写入
  3. 配置 min-slaves-max-lag:限制从节点与主节点的最大复制延迟
  4. 使用异步复制:Redis 2.8+ 支持部分复制,减少全量复制的可能性
  5. 监控复制状态:定期检查主从复制状态,确保从节点正常复制

Q5: 如何测试自动故障转移功能?

A5: 测试自动故障转移功能的方法:

  1. 模拟主节点故障:使用 debug segfault 命令或 kill -9 杀死主节点进程
  2. 监控故障转移过程:观察 Sentinel 或 Cluster 日志,记录故障转移时间和过程
  3. 验证业务连续性:在故障转移过程中,测试客户端是否能够正常访问 Redis 服务
  4. 验证数据一致性:故障转移完成后,检查数据是否一致
  5. 恢复旧主节点:测试旧主节点恢复后是否能正确成为从节点

Q6: 如何处理脑裂问题?

A6: 处理脑裂问题的方法:

  1. Redis Sentinel

    • 配置 min-slaves-to-writemin-slaves-max-lag
    • 确保 Sentinel 节点分布在不同物理机器
  2. Redis Cluster

    • 配置合理的 cluster-node-timeout
    • 确保每个主节点有足够的从节点
    • 启用 cluster-allow-reads-when-down no
  3. 网络层面

    • 配置合理的网络拓扑,避免网络分区
    • 使用专线或高质量网络连接

通过合理配置和优化 Redis 自动故障转移机制,可以有效提高 Redis 服务的高可用性,确保业务连续性。在实际运维中,需要根据业务场景和硬件环境,选择合适的自动故障转移方案,并持续监控和优化。