Redis 哨兵模式

本文最后更新于:2024年3月18日 凌晨

Redis 哨兵模式

  • 哨兵模式能够后台监控主机是否故障,如果故障了则自动将从节点转换为主节点。
  • 原理
    1. 哨兵通过发送命令,等待 Redis服务器响应,从而监控运行的多个 Redis实例,让 Redis服务器返回其运行状态。
    2. 当哨兵监测到主节点宕机,会自动将从节点切换成主节点,然后通过发布订阅模式通知其他的从节点,修改配置文件并切换主节点。
    3. 当主节点恢复连接后,原主节点自动转换为从节点,现主节点不变。
  • 优点
    • 哨兵模式是主从模式的升级,手动转换为自动。
    • 主从可以切换,故障可以转移,系统的可用性更好。

多哨兵模式

  • 单个哨兵进程对 Redis 服务器进行监控,可能会出现问题,可以使用多个哨兵进行监控,各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

流程

  1. 每个Sentinel以每秒钟一次的频率向它所知的Master,Slaver以及其他Sentinel实例发送一个PING命令。

  2. 如果一个实例距离最后一次有效回复PING命令的时间超过own-after-millisecounds选项所指定的值,则这个实例会被Sentinel标记为主观下线。

  3. 当有足够足够数量的Sentinel(大于等于配置文件指定的值)在指定的时间范围内确定Master的确进入了主观下线状态,则Master会被标记为客观下线。

  4. Sentinel从Slave中选出新的Master

    • 剔除主观下线,已断线,或者最后一次回复PING命令的时间大于5s的Slave
    • 剔除与失效主服务器连接断开的时长超过down-after选项指定的时长10倍的Slave
    • 按同步数据的偏移量选出数据最完成的Slave
    • 如果偏移量相同,选中ID最小的Slave
  5. 将Slave切换成Master

    1. 向被选中的从服务器发送SLAVEOF NO ONE命令,让它转成主服务器。
    2. 通过发布于订阅功能,将更新后的配置传播给所有其他Sentinel,其他Sentinel对它们自己的配置进行更新。
    3. 向所有Slave下发SLAVEOF命令,指向新的主服务器。
    4. redis-slave向master重新建立连接,重放rdb保持数据同步。
  • 在上述转移过程中,伴随着Redis本地配置文件的自动重写,这样即使是实例重启配置也不会丢失。
  • 原有的master在恢复后降级为slave与新master全量同步。

哨兵的高可用

  • Sentinel 自动故障迁移使用 Raft 算法来选举Leader Sentinel 用于下发故障转移的指令。
  • 如果某个Leader Sentinel挂了,则使用Raft从剩余的 Sentinel 中选出 Leader

哨兵的感知发现

  • 每一个Sentinel节点接入Master之后,所有Sentinel的信息也在Master节点上进行了注册。
  • Sentinel 可以通过Master获取其他Sentinel节点的信息。

配置Redis哨兵模式

配置文件

配置文件

  • sentinel.conf
1
2
3
4
5
6
7
8
9
10
##sentinel实例之间的通讯端口
daemonize yes
port 27000
#redis-master
sentinel monitor redis-master 127.0.0.1 7000 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 2
sentinel auth-pass redis-master 123456
logfile "/data/bd/redis/sentinel/sentinel.log

配置项

配置项 说明
sentinel monitor <master-name> <ip> <redis-port> <quorum> 哨兵 sentinel监控的Redis主节点的 ip port
master-name可以自己命名的主节点名字只能由字母A-2,数字0-9,这三个字符",-_"组成,
quorum配置多少个 sentinel哨兵统一认为 master主节点失联那么这时客观上认为主节点失联了
sentinel auth-pass <master-name> <password> 当在 Redis实例中开启了 requirepass foobared授权密码这样所有连接 Redis实例的客户端都要提供密码
sentinel down-after-milli seconds<master-name><milliseconds> 指定多少毫秒之后主节点没有应答哨兵哨兵主观上认为主节点下线,默认30秒
sentinel parallet-syncs <master-name><numslaves> 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的 master进行同步,这个数字越小,完成 failover所需的时间就越长但是如果这个数字越大,就意味着越多的slave因为replication而不可用,
可以通过将这个值设为1来保证每次只有一个slave处于不能处理命令请求的状态,
sentinel fallover-timeout <master-name><milli seconds> 故障转移的超时时间 failover- timeout可以用在以下这些方面:
1.同一个 sentinel对同一个 master两次failover之间的间隔时间,
2.当一个save从一个错误的 master那里同步数据开始计算时间,直到 slave被纠正为向正确的 master那里同步数据的时间,
3.当想要取消一个正在进行的fai1over所需要的时间,
4.当进行 failover时,配置所有slaves指向新的 master所需的最大时间,不过,即使过了这个超时, slaves依然会被正确配置为指向 master,但是就不按parallet-syncs所配置的规则来了
默认三分钟(18000)
sentinel notification-script <master-name><script-path> 配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员,对于脚本的运行结果有以下规则
若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行,
如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同,
一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGGKILL信号终止,之后重新执行
通知型脚本:当 sentinel有任何警告级别的事件发生时(比如说 Redis实例的主观失效和容观失效等等),将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息,调用该脚本时,将传给脚本两个参数,一个是事件的类型一个是事件的描述,如果 sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则 sentinel无法正常启动成功
sentinel client-reconfig-script <master-name> <script-path> 客户端重新配置主节点参数脚本:当一个 master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于 master地址已经发生改变的信息
以下参数将会在调用脚本时传给脚本 <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
目前<state>总是" failover <ro1e>是" leader”或者" observer"中的一个,
参数from-ip,from-port,to-ip,to-port是用来和旧的 master和新的master(即旧的slave)通信的这个脚本应该是通用的,能被多次调用,不是针对性的,

运行哨兵模式

  • Master->Slave->Sentinel,要确保按照这个顺序依次启动。
  • Sentinel的启动命令和Redis类似,终端输入:
1
redis-sentinel ~/sentinel.conf
  • 启动成功后可以通过Redis客户端工具查看当前Sentinel的信息,终端输入:
1
2
3
4
5
6
7
8
9
redis-cli -p 27000-h 127.0.0.1
127.0.0.1 redis> INFO Sentinel

# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=redis-master,status=ok,address=192.168.1.51:7000,slaves=2,sentinels=3

sentinel日志

  • 日志路径在配置文件中设置,终端输入:
1
2
3
4
5
6
7
8
tail -f/data/bd/redis/sentinel/sentinel.log

3273:X 08 Apr 10:44:14.733 # Sentinel runid is 725b3bc06f18e8db913a44bbbdbc23a3be54c4d1
3273:X 08 Apr 10:44:14.733 # +monitor master redis-master 192.168.1.51 7000 quorum 2
3273:X 08 Apr 10:44:14.735 * +slave slave 192.168.1.52:7000 192.168.1.52 7000 @ redis-master 192.168.1.51 7000
3273:X 08 Apr 10:44:14.744 * +slave slave 192.168.1.53:7000 192.168.1.53 7000 @ redis-master 192.168.1.51 7000
3273:X 08 Apr 10:48:12.733 * +sentinel sentinel 192.168.1.52:27000 192.168.1.52:27000 @ redis-master 192.168.1.51 7000
3273:X 08 Apr 10:48:20.533 * +sentinel sentinel 192.168.1.53:27000 192.168.1.53:27000 @ redis-master 192.168.1.51 7000
  • +slave表示成功发现了从节点。
  • +sentinel表示成功发现了Sentinel
  • +sdown 表示哨兵主观认为节点下线。
  • +odown 表示哨兵客观认为节点下线。
  • +try-failover 表示哨兵开始进行故障恢复。
  • +failover-end 表示哨兵完成故障修复,其中包括了领头哨兵的选举,备选从节点的选择等等较为复杂的过程。
  • +switch-master表示完成主节点迁移。

查看sentinel.conf

  • 重新打开sentinel.conf文件,发现sentinel自动生成了一些信息,记录了监控过程中的状态变化。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
##sentinel实例之间的通讯端口
daemonize yes
port 27000
#redis-master
sentinel monitor redis-master 192.168.1.51 7000 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 2
sentinel auth-pass redis-master 123456
logfile "/data/bd/redis/sentinel/sentinel.log"
# Generated by CONFIG REWRITE
dir "/soft/sentinel"
sentinel config-epoch redis-master 0
sentinel leader-epoch redis-master 0
sentinel known-slave redis-master 192.168.1.52 7000
sentinel known-slave redis-master 192.168.1.53 7000
sentinel known-sentinel redis-master 192.168.1.52 27000 ef356da8dadb6a16268d25611942ecf001d5cb2e
sentinel known-sentinel redis-master 192.168.1.53 27000 188fa69f695fd17639ce1ee38592e894d8a14331
sentinel current-epoch 0

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!