Redis高可用之哨兵模式
哨兵模式的原理与功能
哨兵(sentinel)是一个分布式系统,用于对主从架构中的每台服务器进行监控,当出现故障时通过投票机制选举新的master并将所有slave连接新的master。
哨兵的功能:
- 集群监控:负责监控redis master和slave进程是否正常工作。
- 消息通知:如果某个redis服务有故障,那么哨兵负责发送消息通知给管理员。
- 故障转移:如果master结点故障,哨兵可以选举slave结点变为master。
- 配置中心:如果故障转移发生了,通知client客户端新的master地址。
哨兵工作原理:
监控阶段:获取各个sentinel的状态;获取master的状态;获取所有slave的状态(根据master中的slave消息)。之后在哨兵拓扑网络(自动发现机制,通过redis的发布/订阅模式实现)中进行信息交换与共享。
通知阶段:对各个结点发送心跳包,获取状态。
故障转移阶段:当一个哨兵节点发现master下线,进行主观下线(sdown)。将消息在哨兵网络*享,当一定数量的哨兵都觉得master下线了,那就会转为客观下线(odown)。哨兵节点进行投票将master投出,选举一个哨兵节点为负责人,由它在slave中选取新的master节点。
sdown(主观下线)与odown(客观下线)转换机制
如果一个哨兵认为一个master宕机了,那么就是sdown。
如果quorum数量的哨兵都认为master宕机了,那么就是odown。
quorum:确认odown的最少的哨兵数量
majority:授权进行主从切换的最少的哨兵数量
如果一个哨兵 ping 一个 master,超过了 is-master-down-after-milliseconds 指定的毫秒数之后,就主观认为 master 宕机了;如果一个哨兵在指定时间内,收到了 quorum 数量的其它哨兵也认为那个 master 是 sdown 的,那么就认为是 odown 了。
主节点选举
如果一个master被客观下线后,那么就会选举出一个哨兵节点为领导者哨兵(选举的票数大于等于哨兵的个数/2+1时,将会成为领导者),由领导者哨兵将slave转换为master。
选举slave为master需要看以下几点:
跟 master 断开连接的时长
slave 优先级
offset
run id
如果一个slave跟master断开连接时长超过 down-aftermilliseconds的10倍,被认为不适合作为master。
接下来对slave进行排序,slave的priority越低,优先级越高。
如果slave的priority相同,查看offset,offset越靠后的slave复制的数据越全,优先级越高。
如果上面两个都相同,那么选择run id 小的slave。
Redis哨兵主备切换的数据丢失问题
1.异步复制时master宕机导致数据丢失。
2.脑裂导致数据丢失。
脑裂:当master与slave和sentinel的网络出现问题,无法连接,此时sentinel选举出了新的master。但是旧master与client能够进行数据交换,那么当旧master又重新回到哨兵集群时,哨兵会将其设置为slave,将数据清空后进行同步,此时数据丢失。
解决方案:
min-slaves-to-write 1
min-slaves-max-lag 10
一旦slave复制的数据和ack(确认字符)延时过大,可能master已经宕机,那么就拒绝写请求,可以把master宕机时由于部分数据未同步搭配slave导致的数据丢失降低到可控范围内。
如果一个 master 出现了脑裂,跟其他 slave 丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的 slave 发送数据,而且 slave 超过 10 秒没有给自己 ack 消息,那么就直接拒绝客户端的写请求。因此在脑裂场景下,最多就丢失 10 秒的数据。