Redis分布式集群实战(三)——搭建Redis哨兵(Sentinel)模式

一、哨兵模式

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。哨兵模式就是为了解决此类问题而产生的。

1、定义

Sentinel(哨兵)是用于监控redis集群中Master状态的工具,是Redis 的高可用性解决方案,sentinel哨兵模式已经被集成在redis2.4之后的版本中。sentinel系统可以监视一个或者多个redis master服务,以及这些master服务的所有slave;当某个master服务下线时,自动将该master下的slave升级为master服务替代已下线的master服务继续处理请求。

sentinel可以让redis实现主从复制,当一个集群中的master失效之后,sentinel可以选举出一个新的master用于自动接替master的工作,集群中的其他redis服务器自动指向新的master同步数据。一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换。

在这里插入图片描述

2、功能作用

监控(monitoring):Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notifation):当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障转移(Automatic failover):当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

3、原理

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程。其原理是 哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

在这里插入图片描述
这里的哨兵有 两个作用

  • 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
  • 当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。

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

故障切换(failover)的过程:假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程, 仅仅是哨兵1主观的认为主服务器不可用,这个现象成为 主观下线当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为 客观下线。这样对于客户端而言,一切都是透明的,客户端并不知晓。切换后,主备redis配置文件6379.conf和主备redis的sentinel.conf的内容都会发生改变,即主redis的6379.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。

监控同一个Master的Sentinel会自动连接,组成一个分布式的Sentinel系统,互相通信并交换彼此关于被监视服务器的信息。

Sentinel状态持久化
snetinel的状态会被持久化地写入sentinel的配置文件中。每次当收到一个新的配置时,或者新创建一个配置时,配置会被持久化到硬盘中,并带上配置的版本戳。这意味着,可以安全的停止和重启sentinel进程

4、工作方式

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

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

3)如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。

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

5)在一般情况下,每个Sentinel 会以每10秒一次的频率向它已知的所有Master,Slave发送 INFO 命令。

6)当Master被Sentinel标记为客观下线时,Sentinel 向下线的 Master 的所有Slave发送 INFO命令的频率会从10秒一次改为每秒一次

7)若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除 若 Master重新向Sentinel 的PING命令返回有效回复,Master的主观下线状态就会被移除。

定时任务
sentinel在内部有3个定时任务
1)每10秒每个sentinel会对master和slave执行info命令,这个任务达到两个目的:

  • 发现slave节点
  • 确认主从关系

2)每2秒每个sentinel通过master节点的channel交换信息(pub/sub)。master节点上有一个发布订阅的频道(sentinel:hello)。sentinel节点通过__sentinel__:hello频道进行信息交换(对节点的"看法"和自身的信息),达成共识。

3)每1秒每个sentinel对其他sentinel和redis节点执行ping操作(相互监控),这个其实是一个心跳检测,是失败判定的依据。

5、配置文件

1)sentinel monitor <masterName> <ip> <port> <quorum>

四个参数含义:
masterName这个是对某个master+slave组合的一个区分标识(一套sentinel是可以监听多套master+slave这样的组合的)。ip 和 port 就是master节点的 ip 和 端口号。
quorum这个参数是进行客观下线的一个依据,意思是至少有 quorum 个sentinel主观的认为这个master有故障,才会对这个master进行下线以及故障转移(fileover)。因为有的时候,某个sentinel节点可能因为自身网络原因,导致无法连接master,而此时master并没有出现故障,所以这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。

2)sentinel down-after-milliseconds <masterName> <timeout>
这个配置其实就是进行主观下线的一个依据,masterName这个参数不用说了,timeout是一个毫秒值,表示:如果这台sentinel超过timeout这个时间都无法连通master包括slave(slave不需要客观下线,因为不需要故障转移)的话,就会主观认为该master已经下线(实际下线需要客观下线的判断通过才会下线)

那么,多个sentinel之间是如何达到共识的呢?
这就是依赖于前面说的第二个定时任务,某个sentinel先将master节点进行一个主观下线,然后会将这个判定通过sentinel is-master-down-by-addr这个命令问对应的节点是否也同样认为该addr的master节点要做客观下线。最后当达成这一共识的sentinel个数达到前面说的quorum设置的这个值时,就会对该master节点下线进行故障转移。quorum的值一般设置为sentinel个数的二分之一加1,例如3个sentinel就设置2。

二、搭建Redis哨兵模式

在上一篇博客主从复制的基础上搭建哨兵模式。
实验环境

主机名(ip) 角色
server1(172.25.2.1) redis-master
server2(172.25.2.2) redis-slave
server3(172.25.2.3) redis-slave

1、将哨兵配置文件sentinel.conf复制到/etc/redis/
在这里插入图片描述
2、修改配置文件/etc/redis/sentinel.conf

16 bind 0.0.0.0
17 protected-mode no	
85 sentinel monitor mymaster 172.25.2.1 6379 2	
114 sentinel down-after-milliseconds mymaster 10000	

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、将server1配好的sentinel配置文件发送到server2和server3

[root@server1 redis-5.0.3]# scp /etc/redis/sentinel.conf server2:/etc/redis/
[root@server1 redis-5.0.3]# scp /etc/redis/sentinel.conf server3:/etc/redis/
  • 将server1上配好的sentinel文件发送给server2和server3,一定要在server1开启sentinel之前。这是因为sentinel是一个动态的服务。如果开启sentinel,然后再发送,那么sentinel配置文件就不会发生改变。这时,在server2上启动sentinel会报错。

在这里插入图片描述
4、在server1/2/3开启服务sentinel

[root@server1 redis]# redis-server /etc/redis/sentinel.conf --sentinel
[root@server2 redis]# redis-server /etc/redis/sentinel.conf --sentinel
[root@server3 redis]# redis-server /etc/redis/sentinel.conf --sentinel
  • 注意启动的顺序。首先是主机(server1)的Redis服务进程,然后启动从机的服务进程,最后启动3个哨兵的服务进程。
    在这里插入图片描述在备redis(server2)上:
    在这里插入图片描述
    在备redis(server3)上:
    在这里插入图片描述
    5、在server1上,查看master信息
redis-cli
info

在这里插入图片描述

6、模拟server1(Master)宕机故障,进行测试:
在这里插入图片描述

此时我们,在server2上,可以看到订阅的消息:
在这里插入图片描述
备Redis(server3)上:

在这里插入图片描述此时,我们可以看到server2变为master。

我们可以在server1上远程连接server2的redis客户端,查看状态:看到server2为master

在这里插入图片描述

7、我们再将server1的redis恢复,重新加入主从复制

[root@server1 ~]# /etc/init.d/redis_6379 start

在这里插入图片描述
此时,在server2上,我们可以看到,server1重新上线后,是server2的备机。

在这里插入图片描述此时会发现mster和slave的redis配置文件6379.conf和哨兵配置文件sentinel.conf内容均发生变化:

在server1上:

vim /etc/redis/6379.conf

自动添加最后一行,表明server1是server2的slave
在这里插入图片描述

vim /etc/redis/sentinel.conf

文件最后自动添加了,sentinel监控状况
在这里插入图片描述

在server2上:

vim /etc/redis/6379.conf

在这里插入图片描述

vim /etc/redis/sentinel.conf

在这里插入图片描述
在server3上:

vim /etc/redis/6379.conf

自动更新为新的master的ip
在这里插入图片描述

vim /etc/redis/sentinel.conf

在这里插入图片描述

三、故障转移的具体步骤:

1)从下线的主服务的所有从服务里面挑选一个从服务,将其转成主服务
sentinel状态数据结构中保存了主服务的所有从服务信息,领头sentinel按照如下的规则从从服务列表中挑选出新的主服务;
删除列表中处于下线状态的从服务;
删除最近5秒没有回复过领头sentinel info信息的从服务;
删除与已下线的主服务断开连接时间超过 down-after-milliseconds*10毫秒的从服务,这样就能保留从的数据比较新(没有过早的与主断开连接);
领头sentinel从剩下的从列表中选择优先级高的,如果优先级一样,选择偏移量最大的(偏移量大说明复制的数据比较新),如果偏移量一样,选择运行id最小的从服务。

2)已下线主服务的所有从服务改为复制新的主服务
挑选出新的主服务之后,领头sentinel 向原主服务的从服务发送 slaveof 新主服务 的命令,复制新master。

3)将已下线的主服务设置成新的主服务的从服务,当其回复正常时,复制新的主服务,变成新的主服务的从服务
同理,当已下线的服务重新上线时,sentinel会向其发送slaveof命令,让其成为新主的从。

温馨提示: 还可以向任意sentinel发生sentinel failover 进行手动故障转移,这样就不需要经过上述主客观和选举的过程

发布了125 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ranrancc_/article/details/104283802