Redis学习之哨兵模式

上一章介绍了Redis的主从复制、读写分离,就是主机执行写命令,Slave从机能同步主机的数据,这样就是实现了主从复制,读写分离。但是万一Master主机由于某些原因挂了怎么办,这是个麻烦事情,为了解决重要问题,Redis提供了一个Sentinel机制(哨兵),以此来实现主从切换的功能,类似于zookeeper。

1、Sentinel的简介

Redis在主从复制模式中,如果出现Master主机挂掉的情况,Slave从节点并不会切换为Master主节点,那么Slave从节点会一直等待Master重新启动,这显然是不合理的,为了解决这一问题,就出现了Redis的哨兵模式(Sentinel),见名之意,哨兵巡逻监控。Sentinel主要功能:监控Redis集群中的Master主服务器时运行状态,若Master节点出现问题,能够选举出一个Slave从节点变为主节点,从而保证系统的高可用,它们通过投票的方式进行选择,但拥有50%以上投票才生效,所以至少要3个Sentinel节点,所以单个Sentinel是不可靠的。Redis哨兵模式是支持集群的,并且集群模式下的哨兵之间会自动监控

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。Sentinel由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

例如下图所示:

image

在Server1 掉线后:

image

升级Server2 为新的主服务器:

image

2、Sentinel的作用

  • 监控(Monitoring):哨兵(Sentinel)会不断地检查你的Master和Slave是否运作正常。
  • 提醒(Notification):当被监控的某个Redis节点出现问题时,哨兵(Sentinel)可以通过API向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(Sentinel)会开始一次自动故障迁移操作。
    • 它会将失效Master的其中一个Slave升级为新的Master,并让失效Master的其他Slave改为复制新的Master;
    • 当客户端视图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效的Master。
    • Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即Master主服务器的redis.conf配置文件中会多一行Slave的配置,sentinel.conf的监控目标会随之调换。

3、Sentinel的工作方式

  1. 每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令 
  2. 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds (毫秒)选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。 
  3. 如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。 
  4. 当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态,并且当哨兵认为主观下线的票数超过了quorum(选举)个数, 则Master会被标记为客观下线 。
  5. 在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令 。
  6. 当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次 。
  7. 若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。 
  8. 若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。

4、Sentinel的配置(多机)

虽然哨兵模式可以切换主从节点,但是当哨兵机器挂了之后,就无法进行监控了,解决办法是哨兵也建立集群,Redis哨兵模式是支持集群的。所以配置3个哨兵和1主2从的Redis服务器来演示这个过程。

imageimage

下面配置Redis的主从服务器,修改redis.conf文件如下:

(1)、配置Master节点

①、注释bind 127.0.0.1

image

②、禁止保护模式:protected-mode no

image

③、修改daemonize为yes

image

④、设置密码(可选,不建议设置密码,所以我就没有设置密码了):requirepass 123456

image

-------------------------------------------------------------

(2)配置Slave节点(在上面的基础Slave节点还需额外配置下面的信息)

①、指定主服务器。注意:只配置从服务器,主服务器不需要配置:replicaof 192.168.30.101 6379

image

具体可以参考上一章:Redis学习(六)----主从复制、读写分离

(3)、然后分别配置3个哨兵,每个哨兵的配置都是一样的。在Redis安装目录下有一个sentinel.conf文件,copy进行修改

①、设置哨兵后台启动

image

②、配置哨兵输出日志

image

③、设置哨兵监控的节点

image

(4)、开启端口:需要开启6379 和 26379 这两个端口,Linux打开端口可以参考:Linux开放指定端口(CentOS6/CentOS7)(转)

# 开启6379
firewall-cmd  --zone=public --add-port=6379/tcp --permanent
# 开启26379
firewall-cmd  --zone=public --add-port=26379/tcp --permanent
# 重启防火墙
firewall-cmd –reload
# 查看端口是否开放
firewall-cmd --list-ports

(5)、当上述步骤都完成之后,我们可以进入Redis的安装目录启动Redis服务和哨兵了,通过下面的命令启动服务器和哨兵

# 进入redis安装目录bin下
cd /usr/local/redis/bin
# 依次启动Redis服务器进程
./redis-server redis.conf
# 依次启动哨兵进程
./redis-sentinel sentinel.conf

# 进入redis客户端
./redis-cli -h 192.168.30.101 -p 6379
./redis-cli -h 192.168.30.102 -p 6379
./redis-cli -h 192.168.30.103 -p 6379

imageimageimage

通过 info replication 可以发现Redis主从和哨兵都启动了,并且主从关系以及建立起来了。

然后我们将Master服务关闭(即:192.168.30.101:6379),通过ShutDown命令。

image

这时Master主机就挂了,哨兵监控到就会马上进行投票选出一个从机作为新的Master主机,稍微等待几秒钟之后,通过查看日志可以发现,IP地址为 192.168.30.103:6379 成为了新的主机,同时,192.168.30.102:6379 和挂掉的主机成为了 192.168.30.102:6379 的从机,我们看看哨兵打印的日志:

image

随后如果Master主机又复活了呢?当之前挂掉的Master主机重新连接上会发生什么情况呢?我们来看一下:

imageimage

可以发现原来挂掉的Master现在已经成为了192.168.30.103:6379的从节点,这样就通过Sentinel机制完成了Redis的高可用性(HA)解决方案。

自此已经完成Redis的状态:“三哨兵集群”、“一主”、“二从”的模式。

5、Sentinel的配置文件参数介绍

最后再来把哨兵机制的配置文件sentinel.conf中常用配置项说明一下:

# 打开非保护模式
protected-mode no
-----------------------------------------------------
# Sentinel使用端口,默认26379 
port 26379
-----------------------------------------------------
# 守护线程启动(即后台启动)
daemonize yes
-----------------------------------------------------
# 守护进程会使用到的一个文件
pidfile /var/run/redis-sentinel.pid
-----------------------------------------------------
# 指定哨兵输出的日志文件名,默认为"",空字符串也可用于强制Sentinel登录标准输出,
# 指定后我们可以通过tail -f xxx.log查看日志
logfile "/usr/local/redis/bin/sentinel.log"
-----------------------------------------------------
# 哨兵sentinel的工作目录 
dir "/tmp"
-----------------------------------------------------
# 是否拒绝从新配置通知脚本,默认拒绝(yes).
sentinel deny-scripts-reconfig yes
-----------------------------------------------------
# 这个配置非常重要!!!
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
# 告诉sentinel去监听地址为ip:port的一个master
# master-name:可以自己命名的主节点名字,只能由字母A-z、数字0-9 、这三个字符".-_"组成。 
# quorum:当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了 
# 有多少个sentinel认为一个master失效时,master才算真正失效.需要注意的是master-ip 要写真实的ip地址而不要用回环地址(127.0.0.1)。
sentinel monitor mymaster 192.168.30.103 6379 1
-----------------------------------------------------
# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提供密码 
# 必须为主从设置一样的验证密码,注意:这一步必须在sentinel monitor后面
# sentinel auth-pass <master-name> <password> 
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
-----------------------------------------------------
# 故障转移的超时时间 failover-timeout 可以用在以下这些方面:
# 1.同一个sentinel对同一个master两次failover之间的间隔时间。
# 2.当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同 步数据时。
# 3.当想要取消一个正在进行的failover所需要的时间。
# 4.当进行failover时,配置所有slaves指向新的master所需的大时间。
#   不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了 
# 时间默认三分钟,单位为毫秒
# sentinel failover-timeout <master-name> <milliseconds> 
sentinel failover-timeout mymaster 180000
-----------------------------------------------------
# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下.单位是毫秒,默认为30秒
# sentinel down-after-milliseconds <master-name> <milliseconds> 
sentinel down-after-milliseconds mymaster 30000
-----------------------------------------------------
# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,这个数字越小,
# 完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用.
# 可以通过将这个值设为1(默认就是1)来保证每次只有一个slave处于不能处理命令请求的状态
# sentinel parallel-syncs <master-name> <numslaves> 
sentinel parallel-syncs mymaster 1
-----------------------------------------------------
# 通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,
# 这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本 时,将传给脚本两个参数,一个是事件的类型,一个是事件的描述。 
# 如果sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentinel无法正常启动成功。 
# 通知脚本,该配置项可选,比较常用
# sentinel notification-script <master-name> <script-path> 
sentinel notification-script mymaster /var/redis/notify.sh
-----------------------------------------------------
# 客户端重新配置主节点参数脚本 
# 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生 改变的信息。 
# 以下参数将会在调用脚本时传给脚本: 
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port> 
# 目前<state>总是“failover”, 
# <role>是“leader”或者“observer”中的一个。 
# 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通信的 
# 这个脚本应该是通用的,能被多次调用,不是针对性的。 
# sentinel client-reconfig-script <master-name> <script-path> 
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

参考链接:

  1. https://www.cnblogs.com/kevingrace/p/9004460.html
  2. https://www.jianshu.com/p/06ab9daf921d
作者: 唐浩荣
本文版权归作者和博客园共有,欢迎转载,但是转载需在博客的合适位置给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/tanghaorong/p/14339453.html