在 Redis 主从复制模式中,因为系统不具备自动恢复的功能,所以当主服务器(master)宕机后,需要手动把一台从服务器(slave)切换为主服务器。在这个过程中,不仅需要人为干预,而且还会造成一段时间内服务器不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。Redis从2.8开始正式提供了Sentinel (哨兵)架构来解决这个问题。
Sentinel 通过监控的方式查看主机是否故障,当主机发生故障时, Sentinel 会自动进行 Failover(即故障转移),并且根据投票数自动将从库转换为主库。
哨兵模式是一种特殊的模式,Redis 为其提供了专属的哨兵命令,它是一个独立的进程,能够独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
基本结构图如下所示:
在上图中,哨兵主要有两个重要作用:
但是,在实际生产情况中,Redis 哨兵模式是集群高可用的保障,为避免意外,它一般是由3-5个节点组成,这样就算挂了个别节点,该集群仍然可以正常运转。其结构图如下所示:
上图所示,多个哨兵之间也存在互相监控,这就形成了多哨兵模式。
主观下线、客观下线、投票选举
主观下线:比如 Sentinel1 向主服务发送了PING
命令,在规定时间内没收到主服务器PONG
回复,则 Sentinel1 判定主服务器为“主观下线”。
客观下线:Sentinel1 发现主服务器出现了故障,它会通过相应的命令,询问其它 Sentinel 节点对主服务器的状态判断。如果数量达到一定值时, Sentinel 节点认为主服务器 down 掉,则 Sentinel1 节点判定主服务为“客观下线”。
投票选举:所有 Sentinel 节点会通过投票机制,按照谁发现谁去处理的原则,选举 Sentinel1 为领头节点去做 Failover(故障转移)操作。Sentinel1 节点则按照一定的规则在所有从节点中选择一个最优的作为主服务器,然后通过发布订阅模式通知其余的从节点(slave)更改配置文件,跟随新上任的主服务器(master)。至此就完成了主从切换的操作。
哨兵负责监控主从节点的“健康”状态。当主节点挂掉时,自动选择一个最优的从节点切换为主节点。
客户端来连接Redis集群时,会首先连接哨兵,通过哨兵来查询主节点的地址,然后再去连接主节点进行数据交互。当主节点发生故障时,客户端会重新向哨兵要地址,哨兵会将最新的主节点地址告诉客户端。因此应用程序无需重启即可自动完成主从节点的切换。
目前状态:一主二从!
首先新建 sentinel.conf 文件,并对其进行配置,如下所示:
port 26379
Sentinel monitor myredis 127.0.0.1 6379 1
如果有多个哨兵,就配置多个sentinel.conf 文件(port,monitor)。
哨兵的配置文件
# Example sentinel.conf
# 哨兵sentinel 实例运行的端口 默认26379
port 26379
# 哨兵 sentinel 的工作目录(默认)
dir /tmp
# 哨兵sentinel监控的redis主节点 host port
# master-name :可以自己命名的主节点的名字,只能由字母,数字,“._-”组成
# quorum : 配置多少个sentinel哨兵统一认为master 主节点失联,那么这个时候就客观的认为失联了
# sentinel monitor master-name host port quorum
sentinel monitor myredis 127.0.0.1 6379 2
# 在Redis实例中开启了密码,这时,所有连接Redis的客户端都需要密码
# 设置了哨兵sentinel 连接上主从的密码,注意必须设置一样的验证码
# sentinel auth-pass master-name password
sentinel auth-pass myredis 123456
# 指定多少毫秒后 主节点没有回答哨兵sentinel 此时 哨兵主观上认为主节点离线 默认30秒
# sentinel down-after-milliseconds
sentinel down-after-milliseconds myredis 30000
# 这个配置指定了在发生failover 主备切换时最多可以由多少个slave同时对新的master进行同步
- 这个数字越小,完成failover 所需的时间越长
- 这个数字越大,就意味着越多的slave 因为repkication 而不可用
- 可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态
# sentinel parallel-syncs
sentinel parallel-syncs myredis 1
# 故障转移的时间 failover-timeout 可以用一下这些方面
同一个sentinel 对同一个master 两次failover 之间的间隔时间
当想要取消一个正在进行的fai1over所需要的时间,直到slave 被纠正为向正确的master那里同步数据时
当进行fai1over时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,s1aves依然会被正确配置为指向 master,但是就不按para11e1-syncs所配置的规则来了
# sentinel failover-timeout 默认三分钟
sentinel failover-timeout myredis 180000
# 8、配置当某一个事件发生时需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时,发送
邮件通知相关人员
- 对于脚本的运行结果有以下规则:
1.若脚本执行后返回1,那么该脚本稍后会重新执行,重复次数默认为10
2.若脚本执行后返回2,或者是比2更高的返回值,脚本将不会执行
3.若脚本在执行过程中由于收到系统中断信号被终止了,则同返回值1的时候的相同
4.一个脚本执行的最大时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,重新执行
- 通知型脚本:当sentine1有任何警告级别的事件发生时(比如说re dis实例的主观失效和客观失效等等),将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行行的信息。调用该脚本时,将传给脚本两个参数,一个是事件的类型,一个是事件的描述。如果sentine1.conf配置文件中配置了这个脚本路路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则 sentine1无法正常启动成功。
# sentinel notification-script
sentinel notification-script myredis /var/redis/notify.sh
# 客户端重新配置主节点参数脚本
- 当一个master 发生改变时,这个脚本就会被调用,通知相关的客户端关于 master 地址已经发生改变
- 一下参数将会在调用脚本的时候传给脚本
1. <master-name> <role> <state> <from-ip><from-port><to-ip><to-port>
2. 目前<state>总是"failover”
3. 是" leader"或者"observer”中的一个。
4. 参数from-ip,from-port,to-ip,to-port是用来和旧的master和新的master(即旧的s1ave)通信的
5. 这个脚本应该是通用的,能被多次调用,不是针对性的
# sentinel client-reconfig-script
sentinel client-reconfig-script myredis /var/redis/reconfig.sh
[root@VM-0-4-centos bin]# redis-sentinel zmconfig/sentinel.conf
首先直接将主服务器的 Redis 服务终止:
然后查看从服务器是否被提升为了主服务器(等待哨兵是否有响应,有响应再查看):
这时候80就变为了主服务器!
哨兵日志
如果原先的主机重新连接,那么他会变为从机:
遇到的问题
在主机宕机后,在从机操作,出现如下问题:
解决办法:
将redis服务器配置文件中的 protected-mode 设置为no