Redis 哨兵模式详解:实现高可用的自动故障转移方案
在 Redis 的主从复制架构中,虽然解决了数据备份和读写分离的问题,但当主节点发生故障时,需要人工介入进行主从切换,这在大规模应用中显然无法满足高可用性需求。为此,Redis 从 2.8 版本开始引入了 Sentinel(哨兵)机制,实现了主节点故障的自动检测和故障转移功能。本文将详细介绍 Redis 哨兵模式的工作原理、配置方法及实践要点。
一、哨兵模式核心概念
1.1 哨兵的作用
哨兵(Sentinel)是 Redis 提供的一种高可用解决方案,其核心功能包括:
- 持续监控主从节点的运行状态
- 当主节点故障时自动进行故障转移
- 通知客户端新的主节点地址
- 自动更新主从配置信息
1.2 主观宕机与客观宕机
哨兵机制中存在两种节点状态判断:
- 主观宕机(SDOWN):单个哨兵进程判断某个节点不可用(如指定时间内未收到响应)
- 客观宕机(ODOWN):多数哨兵进程(通常超过半数)都判断主节点为 SDOWN 状态,经过协商后确认的宕机状态
只有当主节点被判定为客观宕机时,才会触发故障转移流程。
1.3 故障转移的选举策略
当主节点被判定为客观宕机后,哨兵会从剩余的从节点中选举新的主节点,选举遵循以下优先级:
- 优先级优先:通过
replica-priority
配置(默认 100,值越小优先级越高) - 数据完整性优先:选择偏移量最大的从节点(即同步主节点数据最完整的节点)
- 运行 ID 优先:在以上条件相同时,选择 runid(实例启动时生成的 40 位唯一标识)最小的节点
1.4 哨兵集群规模
为保证哨兵机制的可靠性,建议哨兵节点数量:
- 至少 3 个节点
- 最好为奇数(避免投票时出现平票)
二、哨兵模式配置实践
2.1 环境准备
本文将配置一主两从三哨兵的架构,节点信息如下:
- 主节点:192.168.2.20:6379
- 从节点 1:192.168.2.21:6379
- 从节点 2:192.168.2.22:6379
- 三个哨兵分别部署在以上三台服务器,端口均为 26379
2.2 配置主从复制
主节点配置(192.168.2.20):
# 安装Redis
[root@redis-master ~]# yum install redis -y
# 编辑配置文件
[root@redis-master ~]# vim /etc/redis/redis.conf
# 修改以下配置
bind 0.0.0.0
protected-mode no
daemonize no
# 重启服务
[root@redis-master ~]# systemctl restart redis
验证主节点状态:
[root@redis-master ~]# redis-cli
127.0.0.1:6379> info replication # 应显示role:master及连接的从节点信息
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.2.22,port=6379,state=online,offset=56,lag=1
slave1:ip=192.168.2.21,port=6379,state=online,offset=56,lag=1
master_failover_state:no-failover
master_replid:f9a6754f8b46599474ad5b3f84945af03513fbd9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:70
从节点配置(192.168.2.21 和 192.168.2.22):
# 安装Redis(同上)
# 编辑配置文件
[root@redis-slave1 ~]# vim /etc/redis/redis.conf
# 修改基础配置
bind 0.0.0.0
protected-mode no
daemonize no
# 添加主节点信息
replicaof 192.168.2.20 6379
# 重启服务
[root@redis-slave1 ~]# systemctl restart redis
验证从节点状态:
[root@redis-slave1 ~]# redis-cli
127.0.0.1:6379> info replication # 应显示role:slave及对应的主节点信息
# Replication
role:slave
master_host:192.168.2.20
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:70
slave_repl_offset:70
slave_priority:100
slave_read_only:1
slave2同slave1
2.3 配置哨兵集群
在主节点(192.168.2.20)上配置哨兵:
vim /etc/redis/sentinel.conf
# 添加以下核心配置
port 26379 # 哨兵监听端口
daemonize no # 后台运行
pidfile /var/run/redis-sentinel.pid
logfile /var/log/redis/sentinel.log
# 监控主节点:名称为mymaster,地址192.168.2.20:6379,需要2个哨兵确认宕机
sentinel monitor mymaster 192.168.2.20 6379 2
sentinel down-after-milliseconds mymaster 30000 # 30秒未响应视为宕机
sentinel parallel-syncs mymaster 1 # 故障转移后同时同步的从节点数
sentinel failover-timeout mymaster 180000 # 故障转移超时时间(3分钟)
将配置文件复制到其他两个哨兵节点:
scp /etc/redis/sentinel.conf root@192.168.2.21:/etc/redis/
scp /etc/redis/sentinel.conf root@192.168.2.22:/etc/redis/
启动所有哨兵(分别在三台服务器执行):
# 方式一:后台启动
redis-sentinel /etc/redis/sentinel.conf &
# 方式二:通过系统服务启动
systemctl start redis-sentinel
#两者选其一,不能同时用
⚠️ 注意:哨兵启动后会自动修改 sentinel.conf 文件,如需重新配置,建议删除原文件后重新编辑。
三、故障转移测试
3.1 模拟主节点故障
在主节点(192.168.2.20)执行:
[root@redis-master ~]# redis-cli
127.0.0.1:6379> SHUTDOWN # 关闭主节点
# 或使用systemctl stop redis
3.2 验证故障转移结果
在从节点 2(192.168.2.22)查看状态:
[root@redis-slave2 ~]# redis-cli
127.0.0.1:6379> info replication # 应显示role:master,并有一个从节点(192.168.2.21)
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.2.21,port=6379,state=online,offset=83956,lag=0
master_failover_state:no-failover
master_replid:d02e650fcd4fcb390363b7c1ea0701ed236600a6
master_replid2:f9a6754f8b46599474ad5b3f84945af03513fbd9
master_repl_offset:84099
second_repl_offset:73296
repl_backlog_active:1
在从节点 1(192.168.2.21)查看状态:
[root@redis-slave1 ~]# redis-cli
127.0.0.1:6379> info replication # 应显示role:slave,主节点变为192.168.2.22
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.2.22
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:92749
slave_repl_offset:92749
slave_priority:100
slave_read_only:1
3.3 原主节点恢复后的状态
重启原主节点(192.168.2.20):
[root@redis-master ~]# systemctl start redis
[root@redis-master ~]# redis-cli
127.0.0.1:6379> info replication # 原主节点将变为从节点,主节点为192.168.2.22
# Replication
role:slave
master_host:192.168.2.22
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:138886
slave_repl_offset:138886
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:7854d09b93aee75454ee12c3bebb5c90eb98c871
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:138886
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:136209
repl_backlog_histlen:2678
四、生产环境注意事项
4.1 数据一致性问题
由于主从同步存在延迟,在高负载场景下可能导致数据不一致。解决办法:
# 配置主节点至少需要2个从节点正常同步才允许写入
[root@redis-slave2 ~]# redis-cli
127.0.0.1:6379> config get min-slaves-to-write
1) "min-slaves-to-write"
2) "0"
127.0.0.1:6379> config set min-slaves-to-write 2
OK
127.0.0.1:6379> config get min-slaves-to-write
1) "min-slaves-to-write"
2) "2"
# 永久生效需写入redis.conf
4.2 网络分区问题
当主节点与从节点 / 哨兵发生网络分区时,可能出现:
- 哨兵误认为主节点宕机并选举新主节点
- 原主节点恢复后会自动变为从节点
- 原主节点在网络分区期间的写入数据会被清空
4.3 哨兵集群维护
- 定期备份哨兵配置文件(哨兵运行中会自动更新)
- 监控哨兵日志,及时发现异常
- 避免哨兵与 Redis 节点部署在同一物理机,防止单点故障
五、总结
Redis 哨兵模式通过自动故障转移解决了主从架构的高可用问题,但其仍存在单个主节点的性能瓶颈。在实际应用中,应根据业务规模选择合适的架构:
- 中小规模应用:哨兵模式足以满足需求
- 大规模应用:建议考虑 Redis Cluster 集群方案
通过合理配置哨兵参数和主从策略,可以有效提升 Redis 服务的可用性和数据安全性,为业务系统提供稳定可靠的缓存支持