Redis集群方案——哨兵机制
Redis Sentinel(哨兵)是Redis官方提供的高可用性(HA)解决方案,用于管理Redis主从架构并实现自动故障转移。
一、集群结构和作用
哨兵是一个分布式系统,由多个哨兵节点组成:
哨兵的作用如下:
监控:Sentinel 会不断检查您的master和slave是否按预期工作
自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主
通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端
二、哨兵工作原理
Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:
- 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线。
- 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。
三、集群故障恢复原理
1.哨兵选主规则
一旦发现master故障,sentinel需要在salve中选择一个作为新的master,选择依据是这样的:
首先会判断slave节点与master节点断开时间长短,如果超过指定值(down-after-milliseconds * 10)则会排除该slave节点
然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举
如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高
最后是判断slave节点的运行id大小,越小优先级越高。
2.故障转移流程
当选出一个新的master后,该如何实现切换呢?
流程如下:
sentinel给备选的slave1节点发送slaveof no one命令,让该节点成为master
sentinel给所有其它slave发送slaveof 192.168.206.180 7002 命令,让这些slave成为新master的从节点,开始从新的master上同步数据。
最后,sentinel将故障节点标记为slave,当故障节点恢复后会自动成为新的master的slave节点
四、Docker搭建Redis哨兵集群
五、相关面试问题
1.怎么保证redis的高并发高可用?
redis提供了主从同步+哨兵模式保证了redis的高并发和高可用性。
首先,主从同步保证了redis的高并发性:单节点redis的并发能力是有上线的,我们可以搭建主从同步集群实现redis的读写分离:master负责写数据,slave只负责读数据。
然后,哨兵机制保证了redis的高可用性:哨兵机制可以实现主从集群的自动故障恢复,里面就包含了对主从服务的检测、自动故障恢复和通知;如果master故障,sentinel会重新选取一个slave作为新的master,当master恢复会自动下降为slave。同时当redis实现故障转移,sentinel会向redis客户端通知信息变化。
2.如何解决redis的集群脑裂问题
redis的哨兵模式一般会因为网络等原因出现脑裂问题。也就是,master、slave和sentinel处于不同的网络分区,sentinel心跳机制检测不到master,会重新选举一个slave作为新的master,但是旧的master并未下线,仍在写入数据,新的master无法同步,当网络恢复,旧的master下降为slave,就会导致丢失大量数据。
我知道的有以下几种方法可以避免和减轻脑裂问题:
第一,设置合适的哨兵quonum,一般为N/2+1(其中N为哨兵节点数)。
第二,启用主节点写入保护,在redis.conf中添加:至少要有1个从节点连接(min-slaves-to-write 1)和从节点复制延迟不超过10秒(min-slaves-max-lag 10)才能同步数据。