Redis Sentinel高可用方案
约 1613 字大约 5 分钟
redissentinel
2025-05-09
Redis Sentinel 是 Redis 官方提供的高可用解决方案,实现了主节点的自动故障检测和故障转移(Failover),保证 Redis 服务的持续可用。
Sentinel 架构
Sentinel 的核心职责
| 职责 | 说明 |
|---|---|
| 监控 (Monitoring) | 持续检查 Master 和 Replica 是否正常 |
| 通知 (Notification) | 通过 Pub/Sub 通知客户端和管理员 |
| 自动故障转移 (Failover) | Master 不可用时自动将 Replica 提升为新 Master |
| 配置提供者 (Configuration Provider) | 客户端通过 Sentinel 发现当前 Master 地址 |
监控机制
心跳检测
主观下线 (SDOWN) 与客观下线 (ODOWN)
# 主观下线超时(毫秒)
sentinel down-after-milliseconds mymaster 30000
# quorum 数量:至少多少个 Sentinel 同意才认为客观下线
sentinel monitor mymaster 192.168.1.100 6379 2
# 最后的 2 就是 quorumSDOWN vs ODOWN:
- SDOWN(主观下线):单个 Sentinel 认为节点不可达,可能是网络分区
- ODOWN(客观下线):多数 Sentinel 达成共识,确认节点真的不可用
- Replica 只有 SDOWN,没有 ODOWN(不触发 Failover)
Leader 选举 (Raft)
当 Master 被标记为 ODOWN 后,Sentinel 集群需要选出一个 Leader 来执行 Failover。
选举规则:
- 每个 Sentinel 在每个 epoch 只能投一票(先到先得)
- 获得
max(quorum, N/2+1)票的 Sentinel 成为 Leader - 如果选举失败,增加 epoch 重新选举
Failover 流程
# Replica 优先级(值越小优先级越高,0 表示不参与选举)
replica-priority 100
# Failover 超时
sentinel failover-timeout mymaster 180000 # 毫秒配置详解
Sentinel 配置文件
# sentinel.conf
port 26379
daemonize yes
logfile "/var/log/redis/sentinel.log"
dir /var/lib/redis
# 监控的 Master(名称, IP, 端口, quorum)
sentinel monitor mymaster 192.168.1.100 6379 2
# 连接 Master 的密码
sentinel auth-pass mymaster your_password
# 主观下线超时
sentinel down-after-milliseconds mymaster 30000
# Failover 超时
sentinel failover-timeout mymaster 180000
# Failover 后同时对新 Master 进行复制的 Replica 数量
sentinel parallel-syncs mymaster 1
# Sentinel 通知脚本(可选)
sentinel notification-script mymaster /opt/scripts/notify.sh
# Failover 后客户端重配脚本(可选)
sentinel client-reconfig-script mymaster /opt/scripts/reconfig.sh启动 Sentinel
# 方式一
redis-sentinel /path/to/sentinel.conf
# 方式二
redis-server /path/to/sentinel.conf --sentinel客户端连接
客户端不应直接连接 Master IP,而应通过 Sentinel 发现当前 Master。
Java (Jedis) 示例
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.101:26379");
sentinels.add("192.168.1.102:26379");
sentinels.add("192.168.1.103:26379");
JedisSentinelPool pool = new JedisSentinelPool(
"mymaster", // Master 名称
sentinels,
poolConfig,
3000, // 连接超时
"password" // Redis 密码
);
try (Jedis jedis = pool.getResource()) {
jedis.set("key", "value");
}Python (redis-py) 示例
from redis.sentinel import Sentinel
sentinel = Sentinel([
('192.168.1.101', 26379),
('192.168.1.102', 26379),
('192.168.1.103', 26379),
], socket_timeout=0.5)
# 获取 Master 连接
master = sentinel.master_for('mymaster', password='password')
master.set('key', 'value')
# 获取 Replica 连接(用于读操作)
slave = sentinel.slave_for('mymaster', password='password')
value = slave.get('key')客户端 Failover 感知
Sentinel 命令
# 查看 Master 信息
SENTINEL masters
SENTINEL master mymaster
# 查看 Replica 信息
SENTINEL replicas mymaster
# 查看其他 Sentinel
SENTINEL sentinels mymaster
# 获取当前 Master 地址
SENTINEL get-master-addr-by-name mymaster
# 手动触发 Failover
SENTINEL failover mymaster
# 重置 Sentinel 状态
SENTINEL reset mymaster
# 检查 quorum 是否满足
SENTINEL ckquorum mymaster常见问题与最佳实践
部署建议
- 至少 3 个 Sentinel,部署在不同机器(避免单点故障)
- quorum 设为 N/2+1(如 3 个 Sentinel 设 quorum=2)
- Sentinel 不要和 Redis 数据节点部署在同一台机器
- 不要使用 Docker 的 NAT 网络,Sentinel 依赖正确的 IP 通信
脑裂问题
# 防止脑裂:Master 检测到连接的 Replica 不足时拒绝写入
min-replicas-to-write 1
min-replicas-max-lag 10
# 至少 1 个 Replica 的延迟不超过 10 秒,否则 Master 拒绝写入Sentinel vs Redis Cluster
| 维度 | Sentinel | Cluster |
|---|---|---|
| 数据分片 | 不支持 | 支持(16384 slot) |
| 容量上限 | 单节点内存 | 多节点总和 |
| 高可用 | 自动 Failover | 自动 Failover |
| 复杂度 | 较低 | 较高 |
| 适用场景 | 数据量适中 | 大数据量 |
总结
- Sentinel 通过 SDOWN/ODOWN 两阶段判断确保故障检测的准确性
- Leader 选举基于 Raft 协议的简化版本,保证只有一个 Sentinel 执行 Failover
- 客户端必须通过 Sentinel 发现 Master 地址,而非硬编码 IP
- 至少部署 3 个 Sentinel 实例,设置合理的 quorum 值
- 配合
min-replicas-to-write防止脑裂导致的数据丢失
贡献者
更新日志
2026/3/14 13:09
查看所有更新日志
9f6c2-feat: organize wiki content and refresh site setup于