Redis Sentinel就是一套高可用监控系统,专门盯着主从集群,主节点挂了能自动把从节点提上来顶替,客户端也能自动感知到新主节点的地址。
一,作用
它干三件事:
1)监控 :每秒给所有Redis节点发PING,看谁没响应
2)故障转移: 主节点挂了,从从节点里选一个升级成新的主节点
3)通知: 把新主节点的地址推送给客户端和其他从节点
典型的哨兵架构长这样:
- 3个哨兵节点组成集群,互相通信
- 1个Redis主节点处理写请求
- 2个Redis从节点做读请求和数据备份
- 哨兵节点监控所有Redis节点的状态
- 主节点挂了,哨兵选出新主节点并通知客户端

二,怎么判断主节点挂了?
哨兵判断节点下线分两步:主观下线 和客观下线
(1),主观下线:单个哨兵的判断

每个哨兵每隔1秒就给所有节点发PING,如果超过 down-after-milliseconds 配置的时间还没收到PING,这个哨兵就认为该节点主观下线了。这个超时时间默认是30秒,生产上一般设置为5-10秒。
(2),客观下线:多个哨兵达成共识

一个哨兵说主节点挂了,可能是网络抖动导致的误判。所以这个哨兵会问其他哨兵:"你们觉得主节点挂没挂?"
其他哨兵收到询问后,也会检查主节点状态,然后投票。如果投"挂了"的票数达到quorum值,就认定主节点客观下线,开始走故障转移流程。quorum一般配成哨兵总数的一半加一,3个哨兵就配2。

三,哨兵Leader选举
确定主节点客观下线后,得选一个哨兵出来主持故障转移,这个哨兵叫Leader。
选举用的是Raft算法的思路:
1)第一个发现主节点主观下线的哨兵成为候选者,先投自己一票
2)然后向其他哨兵拉票:"投我当Leader"
3)每个哨兵手里只有一票,谁先来就投谁,投完就不能改了
4)候选者拿到半数以上的票就当选Leader
如果同时有两个哨兵发起选举,可能出现平票。这时候会等一个随机时间后重新选举。所以哨兵节点数要配成奇数,减少平票概率。
四,新主节点怎么选?
哨兵Leader选出来后,要从剩下的从节点里挑一个当新主节点。选择标准按优先级排 :
1)先看slave-priority配置值,值越小优先级越高,0表示永不参选
2)priority相同就看复制偏移量offset,offset越大说明数据越新
3)offset也相同就比run id,选ID最小的那个

选好新的主节点后,哨兵Leader会:
1)给新主节点发SLAVEOF NO ONE,让它不再是任何人的从节点。
2)给其他从节点发SLAVEOF新主节点IP端口,让他们跟新主节点同步。
3)通过发布订阅机制把新节点地址推给客户端
提问:哨兵模式下客户端是怎么知道主节点地址变了的?
回答:客户端连的是哨兵,不是直接连Redis。客户端启动时先问哨兵:"现在主节点是谁?"哨兵告诉它地址,客户端再去连Redis。主节点切换后,哨兵会通过发布订阅通道推送新地址。Jedis、Lettuce这些客户端库都内置了订阅逻辑,收到通知就自动重连新主节点。所以业务代码不用改,客户端库帮你处理了。
提问:哨兵能保证数据不丢吗?
回答:不能完全保证。主从复制是异步的,主节点写完就返回客户端成功,不等从节点同步完。如果主节点刚写完还没来得及同步就挂了,那这条数据就丢了。可以配置min-slaves-to-write 和min-slaves-max-lag来降低丢数据的概率,要求至少有几个从节点在指定延迟内,否则主节点拒绝写入。但这只是降低概率,不是彻底解决。要强一致可以使用WAIT命令等待从节点同步,或者使用其他支持强一致性的存储系统。