相信很多小伙伴在使用Redis时都遇到过这种糟心事:主节点突然宕机,整个服务直接瘫痪,运维同学半夜爬起来手动切换从节点,手忙脚乱不说,业务还可能损失几个亿…(别问我怎么知道的)。这时候,Redis的哨兵(Sentinel)就闪亮登场了!它就像Redis的“私人医生+自动救火队”,能24小时监控主节点状态,一旦发现主节点“不行了”,立刻自动提拔一个从节点上位,还能通知客户端新主节点地址,彻底解决主从架构的单点故障问题!
今天,笔者就带着大家从0到1吃透Redis哨兵:它到底是什么?如何工作?怎么配置?踩过哪些坑?看完这篇,你绝对能上手搭建一个高可用的Redis集群!
Redis哨兵(Sentinel)是官方提供的高可用(HA)解决方案,本质上是一个分布式监控系统。它不负责存储数据,而是专门“盯着”主从节点的状态:
打个比方,如果把Redis主从集群比作一家餐厅,主节点是“主厨”,从节点是“帮厨”,那哨兵就是“大堂经理”——时刻盯着主厨状态,主厨罢工了立刻找备胎帮厨顶上,还负责告诉顾客(客户端)现在谁是主厨,保证餐厅正常营业!
哨兵会定期(默认1秒)向主节点和所有从节点发送PING
命令,就像保安巡逻一样,检查它们是否“活着”。如果某个节点超过指定时间(down-after-milliseconds
)没回复,哨兵就会标记它为“主观下线”(自己觉得它可能挂了)。
一旦检测到节点异常(比如主节点主观下线),哨兵会立刻向客户端、运维系统发送报警(邮件、短信、钉钉都支持),让你第一时间知道“出事了”!
这是哨兵最核心的功能!当主节点被多数哨兵确认客观下线(不是自己瞎判断,是大家一起投票),哨兵集群会选出一个“领导”(Leader Sentinel),由它完成以下操作:
SLAVEOF NO ONE
命令);SLAVEOF 新主IP 新主端口
);客户端连接Redis时,不用硬编码主节点地址,而是直接连哨兵集群。哨兵会告诉客户端当前主节点的IP和端口,就算主节点切换了,客户端也能自动获取最新地址(通过发布订阅机制)。
要搞懂哨兵如何工作,必须先理解两个关键概念:主观下线(SDOWN)和客观下线(ODOWN)。
哨兵A每隔1秒给主节点发PING
,如果超过down-after-milliseconds
(比如5秒)没收到有效回复(比如超时、返回-LOADING
错误),哨兵A就会认为主节点“主观下线”(SDOWN)。注意,这只是哨兵A自己的判断,可能误判(比如网络延迟)。
哨兵A发现主节点SDOWN后,会向其他所有哨兵发送“投票请求”:“兄弟,我觉得主节点挂了,你咋看?”如果超过半数哨兵(比如3个哨兵需要至少2个同意)也认为主节点SDOWN,那么主节点就被标记为“客观下线”(ODOWN)。这时候,故障转移才会正式启动!
一旦主节点被判定为ODOWN,哨兵集群就要选一个Leader来执行故障转移。选Leader的规则类似“总统选举”:
选好Leader后,它就要干三件大事:
Leader会从存活的从节点中选一个最优秀的当新主,优先级从高到低:
slave-priority
(数值越小越优先,默认100)。比如一个从节点设为slave-priority 50
,另一个是100
,那优先级50的会被选中。Leader给选中的从节点发SLAVEOF NO ONE
命令,让它停止复制原主节点,升级为主节点。
Leader给其他存活的从节点发SLAVEOF 新主IP 新主端口
命令,让它们重新指向新主节点,并开始复制数据。同时,Leader还会更新自己和所有哨兵的配置文件(记录新主节点信息),确保下次监控的是新主。
假设我们有3台机器(或3个Docker容器),IP分别是:
(注意:哨兵必须部署在不同的机器上,避免单点故障!)
首先确保主从节点已经配置好复制关系。在从节点的redis.conf
中添加:
replicaof 192.168.1.100 6379 # 从节点1指向主节点
# 从节点2同理,修改IP即可(如果是多个从节点)
在每个哨兵节点创建sentinel.conf
文件,内容如下(以哨兵1为例):
# 监控主节点:名称、主节点IP、主节点端口、判定客观下线需要的哨兵数(quorum)
sentinel monitor mymaster 192.168.1.100 6379 2
# 主节点主观下线的超时时间(毫秒):5秒收不到回复就标SDOWN
sentinel down-after-milliseconds mymaster 5000
# 故障转移超时时间(毫秒):超过这个时间没完成转移就报错
sentinel failover-timeout mymaster 180000
# 从节点并行同步新主的最大数量(减少同步对性能的影响)
sentinel parallel-syncs mymaster 1
# 可选:主节点认证密码(如果主节点启用了requirepass)
sentinel auth-pass mymaster "your_redis_password"
关键参数解释:
quorum
:判定主节点ODOWN需要的哨兵数量,必须小于哨兵总数(比如3个哨兵设为2,5个设为3)。parallel-syncs
:故障转移后,允许同时向新主同步数据的从节点数量。设为1可以避免多个从节点同时拉取数据,减少主节点压力。在每个哨兵节点执行启动命令:
redis-sentinel /path/to/sentinel.conf
启动后,用以下命令验证哨兵状态:
# 查看所有被监控的主节点
redis-cli -h 192.168.1.103 -p 26379 sentinel masters
# 查看主节点mymaster的详细信息(包括从节点列表)
redis-cli -h 192.168.1.103 -p 26379 sentinel master mymaster
# 查看主节点的从节点
redis-cli -h 192.168.1.103 -p 26379 sentinel slaves mymaster
如果看到主节点状态为ok
,从节点列表正常,说明哨兵启动成功!
很多人为了省事只部署2个哨兵,这是大忌!因为选举Leader需要超过半数支持,2个哨兵时需要2票(自己+另一个),但如果有1个哨兵挂了,剩下的1个无法达成多数,集群就瘫痪了。记住:哨兵数量必须是奇数(3/5/7)。
如果哨兵和主节点之间发生网络分区(比如主节点在一个机房,哨兵在另一个),可能导致部分哨兵认为主节点SDOWN,另一部分认为主节点存活。这时候可能触发多次故障转移,甚至出现“双主”问题。
解决方法:
down-after-milliseconds
参数(比如设为10秒),避免误判;sentinel down-after-milliseconds
的合理值,平衡敏感性和误判率。如果客户端还是直连主节点IP,哨兵就白搭了!一定要用支持哨兵的客户端(如Jedis、Lettuce)。以Java的Jedis为例,配置如下:
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.103:26379");
sentinels.add("192.168.1.104:26379");
sentinels.add("192.168.1.105:26379");
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);
Jedis jedis = pool.getResource(); // 自动获取当前主节点地址
故障转移过程中,主节点切换和从节点同步数据可能需要几秒钟(具体时间取决于数据量和网络),这段时间客户端可能会报“连接拒绝”错误。
优化方法:
failover-timeout
(默认180秒,可设为30秒);repl-diskless-sync
开启无盘复制,减少同步时间)。Redis哨兵通过分布式监控和自动故障转移,完美解决了主从架构的单点故障问题。它就像一个不知疲倦的“运维机器人”,24小时盯着主节点,一旦出问题立刻“换主”,还能让客户端无缝切换地址。
不过,哨兵也不是万能的:它适合小规模集群(单主多从),如果数据量极大(比如100G+),或者需要更细粒度的控制,建议考虑Redis Cluster(分片+高可用)。但对于大多数业务场景,哨兵已经足够稳定可靠!
最后,记住一句话:生产环境部署哨兵,一定要用奇数个实例(3/5个),并部署在不同机器上! 这样才能最大程度避免单点故障,让Redis服务稳如泰山~
如果本文对你有帮助,欢迎点赞收藏,评论区留言讨论你的实战经验!