外观
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 领导者选择最优从节点提升为主节点,选择标准包括:
- 健康状态:从节点必须处于在线状态
- 复制偏移量:选择复制偏移量最大的从节点(数据最完整)
- 优先级:选择
slave-priority配置值最高的从节点 - 运行时间:选择运行时间最长的从节点
- 进程 ID:选择进程 ID 最小的从节点(作为最后选择标准)
3.3 执行故障转移
故障转移的具体步骤:
- 提升从节点为主节点:Sentinel 向选中的从节点发送
SLAVEOF NO ONE命令,将其提升为主节点 - 更新其他从节点:Sentinel 向其他从节点发送
SLAVEOF <new-master-ip> <new-master-port>命令,让它们复制新的主节点 - 更新主节点信息:Sentinel 更新内部记录的主节点信息
- 通知客户端:Sentinel 向客户端发布主节点变更通知
- 旧主节点恢复处理:当旧主节点恢复时,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.sh4.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 故障检测流程
- 节点不可达:当节点 A 向节点 B 发送 PING 消息,在
cluster-node-timeout时间内未收到 PONG 响应 - 标记疑似故障:节点 A 将节点 B 标记为
PFAIL(可能故障) - 传播故障信息:节点 A 通过 Gossip 协议将节点 B 的 PFAIL 状态传播给其他节点
- 确认故障:当超过半数主节点将节点 B 标记为 PFAIL 时,节点 B 被标记为
FAIL(确认故障) - 广播故障信息:将节点 B 的 FAIL 状态广播给所有节点
3. Cluster 故障转移流程
当主节点被标记为 FAIL 后,Cluster 开始执行故障转移流程:
3.1 从节点选举
- 资格检查:从节点必须满足以下条件才能参与选举:
- 与故障主节点的网络连接正常
- 复制偏移量足够接近故障主节点
- 最近一次与故障主节点通信的时间不超过
cluster-node-timeout * 2
- 选举投票:从节点向其他主节点发送
FAILOVER_AUTH_REQUEST消息请求投票 - 获得多数票:当从节点获得超过半数主节点的投票时,成功当选
- 选举限制:每个主节点在一个故障转移周期内只能投票一次
3.2 故障转移执行
- 提升从节点为主节点:当选的从节点执行
SLAVEOF NO ONE命令,提升为主节点 - 接管槽位:新主节点接管原主节点负责的所有槽位
- 广播配置更新:新主节点向所有节点广播
PONG消息,包含新的槽位配置 - 更新其他从节点:其他从节点开始复制新主节点
- 客户端重定向:客户端收到 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 no4.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 Sentinel | Redis Cluster |
|---|---|---|
| 适用架构 | 主从架构 | 分布式集群架构 |
| 故障检测机制 | 主观下线 + 客观下线 | Gossip 协议 + PFAIL/FAIL |
| 故障转移触发条件 | 主节点客观下线 | 主节点被标记为 FAIL |
| 从节点选举方式 | Sentinel 领导者选择 | 从节点选举 + 投票机制 |
| 故障转移时间 | 秒级 | 秒级 |
| 数据分片 | 不支持 | 支持(16384 个槽位) |
| 水平扩展 | 不支持 | 支持 |
| 部署复杂度 | 中等 | 较高 |
| 适用场景 | 中小规模 Redis 部署 | 大规模 Redis 部署 |
自动故障转移最佳实践
1. 部署建议
Sentinel 部署:
- 至少 3 个 Sentinel 节点,分布在不同物理机器
- 与 Redis 实例独立部署
- 配置合理的
down-after-milliseconds和quorum参数
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 故障转移速度的方法:
- 减少
down-after-milliseconds:缩短主观下线检测时间 - 合理设置
quorum:确保快速达成客观下线共识 - 增加 Sentinel 节点数量:提高故障检测和决策速度
- 优化网络环境:减少节点间通信延迟
- 设置合理的
parallel-syncs:加快从节点复制速度
Q3: 如何优化 Redis Cluster 故障转移速度?
A3: 优化 Cluster 故障转移速度的方法:
- 减少
cluster-node-timeout:缩短故障检测时间 - 设置合适的
cluster-slave-validity-factor:加快从节点选举速度 - 增加从节点数量:提高故障转移成功率
- 优化网络环境:减少节点间通信延迟
- 确保从节点复制偏移量接近主节点:减少故障转移后的数据同步时间
Q4: 如何处理自动故障转移过程中的数据丢失问题?
A4: 处理数据丢失问题的方法:
- 启用 AOF 持久化:设置
appendfsync everysec或appendfsync always - 配置
min-slaves-to-write:确保主节点至少有 N 个从节点处于正常复制状态才允许写入 - 配置
min-slaves-max-lag:限制从节点与主节点的最大复制延迟 - 使用异步复制:Redis 2.8+ 支持部分复制,减少全量复制的可能性
- 监控复制状态:定期检查主从复制状态,确保从节点正常复制
Q5: 如何测试自动故障转移功能?
A5: 测试自动故障转移功能的方法:
- 模拟主节点故障:使用
debug segfault命令或kill -9杀死主节点进程 - 监控故障转移过程:观察 Sentinel 或 Cluster 日志,记录故障转移时间和过程
- 验证业务连续性:在故障转移过程中,测试客户端是否能够正常访问 Redis 服务
- 验证数据一致性:故障转移完成后,检查数据是否一致
- 恢复旧主节点:测试旧主节点恢复后是否能正确成为从节点
Q6: 如何处理脑裂问题?
A6: 处理脑裂问题的方法:
Redis Sentinel:
- 配置
min-slaves-to-write和min-slaves-max-lag - 确保 Sentinel 节点分布在不同物理机器
- 配置
Redis Cluster:
- 配置合理的
cluster-node-timeout - 确保每个主节点有足够的从节点
- 启用
cluster-allow-reads-when-down no
- 配置合理的
网络层面:
- 配置合理的网络拓扑,避免网络分区
- 使用专线或高质量网络连接
通过合理配置和优化 Redis 自动故障转移机制,可以有效提高 Redis 服务的高可用性,确保业务连续性。在实际运维中,需要根据业务场景和硬件环境,选择合适的自动故障转移方案,并持续监控和优化。
