为什么需要引入哨兵模式
- 在redis主从复制模式中,因为系统不具备自动恢复的功能,所以当主服务器(master)宕机后,需要手动把一台从服务器(slave)切换为主服务器。
- 在这个过程中,不仅需要人为干预,而且还会造成一段时间内服务器不可用状态,同时数据安全性也得不到保障
- 因此主从模式的可用性较低,不适用线上生成环境。
redis官方推荐一种高可用方案,也就是redis sentinel哨兵模式,它弥补了主从模式的不足。
- Redis Sentinel 是一个分布式架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。
- 如果被标识的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化实时通知给 Redis 应用方
- 整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了 Redis 的高可用问题。
注意,这里的的分布式指的是:redis数据节点、sentinel节点集合、客户端分布在多个物理节点的架构。不要与redis cluster混淆。
如下图所示,redis sentinel与redis主从复制模式只是多了若干sentinel节点,所以redis sentinel并没有针对redis节点做了特殊处理
工作流程
没有sentinel时的故障转移
1)主节点发送故障后,客户端(client)连接主节点失败,两个从节点与主节点连接失败造成复制中断。
2)如图所示,如果主节点无法正常启用,需要选出一个从节点(slave-1),对其执行slave of one命令使其成为新的主节点。
3)原来的从节点(slave-1)成为新的主节点之后,更新应用方的主节点信息,重新启动应用方
4)客户端命令另一个从节点(slave-2)去复制新的主节点
5)待主节点回复之后,让他去复制新的主节点
上述处理过程就可以认为整个服务或者架构的设计不是高可用的, 因为整个故障转移的过程需要人介入。 考虑到这点, 有些公司把上述流程自动化了, 但是仍然存在如下问题:
- 判断节点不可达的机制是否健全和标准
- 如果有多个从节点,怎样保证只有一个被晋升为主节点
- 通知客户端新的从节点机制是否足够健壮。
Redis Sentinel正是用于解决这些问题。
sentinel的自动故障转移
1)主节点出现故障,此时两个从节点与主节点失去连接,主从复制失败。
2)每个 Sentinel 节点通过定期监控发现主节点出现了故障
3)多个 Sentinel 节点对主节点的故障达成一致会选举出其中一个节点作为领导者负责故障转移。
4)Sentinel 领导者节点执行了故障转移,整个过程基本是跟我们手动调整一致的,只不过是自动化完成的。
哨兵模式原理
哨兵模式是一种特殊的模式,redis为其提供了专属的哨兵命令,它是一个独立的进程,能够独立运行。下面使用Sentinel 搭建redis集群,基本结构如下图:
在上图过程中,哨兵主要有两个重要作用:
- 第一:哨兵节点会以每秒一次的频率对每个redis节点发送
PING
命令,并通过redis节点的回复来判断其运行状态 - 第二:当哨兵检测到主服务器发生故障时,会自动在从节点中选择一台slave,将其提升为主服务器,然后使用pubsub发布订阅模式,通知其他的从节点,修改其配置文件,跟随新的主服务器
在实际生产情况中,redis sentinel是集群的高可用保障,为避免sentinel发生意外,它一般是由3~5个节点组成,这样就算挂了个别节点,该集群仍然可以正常运行。其结构图如下:
上图所示,多个哨兵之间也存在互相监控,这就形成了多哨兵模式,现在对该模式的工作过程进行讲解:
- 主观下线:
- 主观下线,适用于主服务器和从服务器。
- 如果在规定的时间内(配置参数:down-after-milliseconds),Sentinel 节点没有收到目标服务器的有效回复,则判定该服务器为“主观下线”
- 比如 Sentinel1 向主服务发送了PING命令,在规定时间内没收到主服务器PONG回复,则 Sentinel1 判定主服务器为“主观下线”。
- 客观下线:
- 客观下线,只适用于主服务器
- Sentinel1 发现主服务器出现了故障,它会通过相应的命令,询问其他Sentinel节点对主服务器的状态判定。如果超过半数以上的Sentinel节点认为主服务器down掉,则Sentinel1 节点判定主服务器“客观下线”
- 投票选举
- 指的是所有Sentinel 节点会通过投票机制,按照谁发现谁去处理的原则,选举Sentinel 1为领头节点去做【故障转移】操作
- Sentinel1节点则按照一定的规则在所有从节点中选择一个最优的作为主服务器,然后通过发布订阅功能通知其他的从节点(slave)更改配置文件,跟随新上任的master。至此就完成了主从切换的操作。
总结:
- Sentinel 负责监控主从节点的“健康”状态
- 当主节点挂掉时,自动选择一个最优的从节点切换为主节点
- 客户端来连接redis集群时,会首先连接Sentinel,通过Sentinel 来查询主节点的地址,然后再去连接主节点进行数据交互
- 当主节点发生故障时,客户端会重新向Sentinel 要地址,Sentinel 会将最新的主节点地址告诉客户端,因此应用程序无需重启就可以自动完成主从节点切换
sentinel配置文件说明
配置项 | 参数类型 | 说明 |
---|---|---|
dir | 文件目录 | 哨兵进程服务的文件存放目录,默认为/tmp |
port | 端口号 | 启动哨兵的进程端口号,默认为26379 |
sentinel down-after-milliseconds | < 服务名称>< 毫秒数(整数)> | 在指定的毫秒数内,如果主节点没有应答哨兵的PING命令,此时哨兵认为服务器主观下线,默认时间为30s |
sentinel parallel-syncs | < 服务名称>< 服务器数(整数)> | 指定可以有多少个redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求就越高 |
sentinel failover-timeout | < 服务名称>< 毫秒数(整数)> | 指定故障转移允许的毫秒数,若超过这个时间,就认为故障转移执行失败,默认为 3 分钟。 |
sentinel notification-script | < 服务名称>< 脚本路径> | 脚本通知,配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。 |
sentinel auth-pass < master-name> < password> | < 服务器名称>< 密码> | 若主服务器设置了密码,则哨兵必须也配置密码,否则哨兵无法对主从服务器进行监控。该密码与主服务器密码相同。 |