Redis Sentinel

您所在的位置:网站首页 哨兵模式怎么回看 Redis Sentinel

Redis Sentinel

2023-11-06 20:03| 来源: 网络整理| 查看: 265

参考链接:https://www.jianshu.com/p/21110d3130bc

Redis Sentinel 哨兵模式,使用场景 数据量不大 + 高可用

原理简介

Redis Sentinel 是 Redis 官方推荐的高可用性(HA)解决方案,这是生产环境中最实用也是最常用的方案。

这里涉及到另一个概念:master-slaver(主从模式)。很好理解,就是常用的主备模式,例如 nginx 的主备模式。一个主 redis 节点可以配置多个从节点,当主节点挂掉时,从节点自动顶上代替主节点,这样就可以有效的避免一个节点挂掉导致整个系统挂掉的问题,实现 redis 服务的高可用。如下图:

master-slaver

但是这个方案需要解决两个基本问题:

如何提前判断各个节点(尤其是主节点)的运行健康状况?当主节点宕机的时候如何从多个从节点中选出一个作为新的主节点并实现自动切换?

这时 Redis Sentinel 应运而生,它主要有以下三个特点:

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

总结来说就是 sentinel 可以监控一个或者多个 master-slaver 集群,定时对每个节点进行健康检查,可以通过 API 发送通知,并自动进行故障转移。这时r redis 结构就变成了

使用了 redis sentinel 之后客户端不再直接连接 redis 节点获取服务,而是使用 sentinel 代理获取 redis 服务,类似 Nginx 的代理模式。那么这里又有一个新问题,就是如果 sentinel 宕机了,那么客户端就找不到 redis 服务了,所以 sentinel 本身也是需要支持高可用。

好在sentinel 本身也支持集群部署,并且各个 sentinel 之间支持自动监控,如此一来 redis 主从服务和 sentinel 服务都可以支持高可用。预期结构如下:

redis sentinel集群

部署实例

master-slaver 一主二从

那么下面我们就来实操一下,以下过程大部分参考 redis 官方 Redis Sentinel 文档。

安装 redis 就不重复了,和单机 redis 一样。

redis 解压后,redis home 目录下有 redis 配置的样例文件,我们不直接在此文件上就行修改,在redis home目录下新建文件夹 master-slave ,将配置文件都放于此目录下,下面是三个 redis 节点配置的关键部分

master 配置文件:redis-6379.conf

port 6379 daemonize yes logfile "6379.log" dbfilename "dump-6379.rdb" dir "/opt/soft/redis/data"

slave-1 配置文件:redis-6380.conf

port 6380 daemonize yes logfile "6380.log" dbfilename "dump-6380.rdb" dir "/opt/soft/redis/data" # 关键配置:将这个 redis 指定为某个第一个 redis 的 slaver slaveof 127.0.0.1 6379

slave-2 配置文件:redis-6381.conf

port 6381 daemonize yes logfile "6381.log" dbfilename "dump-6381.rdb" dir "/opt/soft/redis/data" # 关键配置:将这个 redis 指定为某个第一个 redis 的 slaver slaveof 127.0.0.1 6379

分别启动这三个 redis 服务,启动过程就不罗嗦了,和分别启动三个单机 redis 是一样的,分别指定三个配置文件即可。启动后如下图所示:

image

6379、6380、6381 端口分别在运行一个 redis-server。

接下来查看这三个 redis-server 之间的关系:连接到主 redis 上用 info replication即可查看

image

可以看到当前连接的 redis 服务为 master 角色,下面有两个 slaver,IP 和端口都能看到。

这样我们就顺利的完成了 一主二从 redis 环境的搭建,下面开始搭建 sentinel 集群。

sentinel 集群

sentinel 本质上是一个特殊的 redis,大部分配置和普通的 redis 没有什么区别,主要区别在于端口和其哨兵监控设置,下面是三个典型的 sentinel 配置文件中的关键内容:

sentinel-26379.conf #设置 sentinel 工作端口 port 26379 #后台运行 daemonize yes #日志文件名称 logfile "26379.log" #设置当前 sentinel 监控的 redis ip 和 端口 sentinel monitor mymaster 127.0.0.1 6379 2 #设置判断 redis 节点宕机时间 sentinel down-after-milliseconds mymaster 60000 #设置自动故障转移超时 sentinel failover-timeout mymaster 180000 #设置同时故障转移个数 sentinel parallel-syncs mymaster 1 sentinel-26380.conf #设置 sentinel 工作端口 port 26380 #后台运行 daemonize yes #日志文件名称 logfile "26380.log" #设置当前 sentinel 监控的 redis ip 和 端口 sentinel monitor mymaster 127.0.0.1 6379 2 #设置判断 redis 节点宕机时间 sentinel down-after-milliseconds mymaster 60000 #设置自动故障转移超时 sentinel failover-timeout mymaster 180000 #设置同时故障转移个数 sentinel parallel-syncs mymaster 1

sentinel-26381.conf

#设置 sentinel 工作端口 port 26391 #后台运行 daemonize yes #日志文件名称 logfile "26381.log" #设置当前 sentinel 监控的 redis ip 和 端口 sentinel monitor mymaster 127.0.0.1 6379 2 #设置判断 redis 节点宕机时间 sentinel down-after-milliseconds mymaster 60000 #设置自动故障转移超时 sentinel failover-timeout mymaster 180000 #设置同时故障转移个数 sentinel parallel-syncs mymaster 1

针对几个监控设置的配置做一下详细说明:

sentinel monitor [master-group-name] [ip] [port] [quorum]

这个命令中【master-group-name】是 master redis 的名称;【ip】和【port】分别是其 ip 和端口,很好理解。最后一个参数【quorum】是”投票数“

举个栗子,redis 集群中有3个 sentinel 实例,其中 master 挂掉了,如果这里的票数是2,表示有2个 sentinel 认为 master 挂掉啦,才能被认为是正真的挂掉啦。其中 sentinel 集群中各个 sentinel 之间通过 gossip 协议互相通信。 具体怎样投票还涉及到 redis 集群中的【主观下线】和【客观下线】的概念,后面再详细介绍。

down-after-milliseconds

sentinel 会向 master 发送心跳 PING 来确认 master 是否存活,如果 master 在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个 sentinel 会主观地认为这个 master 已经不可用了。而这个down-after-milliseconds 就是用来指定这个“一定时间范围”的,单位是毫秒。

failover-timeout

这个参数 redis 官方文档中并未做详细说明,但是很好理解,就是 sentinel 对 redis 节点进行自动故障转移的超时设置,当 failover(故障转移)开始后,在此时间内仍然没有触发任何 failover 操作,当前sentinel 将会认为此次故障转移失败。

parallel-syncs

当新master产生时,同时进行 slaveof 到新 master 并进行同步复制的 slave 个数,也就是同时几个 slave 进行同步。因为在 salve 执行 salveof 与新 master 同步时,将会终止客户端请求,因此这个值需要权衡。此值较大,意味着“集群”终止客户端请求的时间总和和较大,此值较小,意味着“集群”在故障转移期间,多个 salve 向客户端提供服务时仍然使用旧数据。

我们配置三个 sentinel 几点组成一个 sentinel 集群,端口分别是 23679,23680,23681

然后就可以启动 sentinel 集群了

启动 sentinel 有两种方式:

redis-sentinel /path/to/sentinel.confredis-server /path/to/sentinel.conf --sentinel

这两种启动方式没有区别,按照顺序分别启动三个 sentinel 节点之后,我们任意连接其中的一个 sentinel 节点查看集群关系,如下图:

 

image

我们连接 26379 这个端口的 sentinel,用 info sentinel命令可以看到这个 sentinel 监控的 master redis 服务的 ip,端口,以及 maste 的 slaver 节点数量,以及 sentinel 的数量。

再连接 26380 这个节点试试:

image

可以看到结果和上面一样。

如此,我们的 sentinel 集群也部署完成了

那么,当前这个 redis sentinel 高可用集群的做种拓扑图如下:

image

高可用故障测试

下面我们来测试一下这个高可用方案的实际能力。

我们手动把一主二从中的主节点 kill 掉:

image

然后连接 6380 节点,查看集群状态:

 

image

可以看到 6380 节点已经自动升级为了 master 节点,还有 6381 这一个 slaver 节点,自动故障转移成功

我们再手动启动 6379 节点,观察集群状态:

image

如图,6379节点重新启动后,自动变成了 6380 节点的从节点。

如此一套完整的 redis 高可用方案就部署完成了。

Redis 主观下线和客观下线

前面说过, Redis 的 Sentinel 中关于下线(down)有两个不同的概念:

主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。 (一个 Sentinel 可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线)

如果一个服务器没有在 master-down-after-milliseconds 选项所指定的时间内, 对向它发送 PING 命令的 Sentinel 返回一个有效回复(valid reply), 那么 Sentinel 就会将这个服务器标记为主观下线。

服务器对 PING 命令的有效回复可以是以下三种回复的其中一种:

返回 +PONG 。返回 -LOADING 错误。返回 -MASTERDOWN 错误。

如果服务器返回除以上三种回复之外的其他回复, 又或者在指定时间内没有回复 PING 命令, 那么 Sentinel 认为服务器返回的回复无效(non-valid)。

注意, 一个服务器必须在 master-down-after-milliseconds 毫秒内, 一直返回无效回复才会被 Sentinel 标记为主观下线。

举个栗子, 如果 master-down-after-milliseconds 选项的值为 30000 毫秒(30 秒), 那么只要服务器能在每 29 秒之内返回至少一次有效回复, 这个服务器就仍然会被认为是处于正常状态的。

从主观下线状态切换到客观下线状态并没有使用严格的法定人数算法(strong quorum algorithm), 而是使用了流言协议: 如果 Sentinel 在给定的时间范围内, 从其他 Sentinel 那里接收到了足够数量的主服务器下线报告, 那么 Sentinel 就会将主服务器的状态从主观下线改变为客观下线。 如果之后其他 Sentinel 不再报告主服务器已下线, 那么客观下线状态就会被移除。

有一点需要注意的是:客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例, Sentinel 在将它们判断为下线前不需要进行协商, 所以从服务器或者其他 Sentinel 永远不会达到客观下线条件。

只要一个 Sentinel 发现某个主服务器进入了客观下线状态, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对失效的主服务器执行自动故障迁移操作。

 

 

哨兵模式

1、哨兵的介绍

sentinal,中文名是哨兵

哨兵是redis集群架构中非常重要的一个组件,主要功能如下

(1)集群监控,负责监控redis master和slave进程是否正常工作 (2)消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员 (3)故障转移,如果master node挂掉了,会自动转移到slave node上 (4)配置中心,如果故障转移发生了,通知client客户端新的master地址

哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作

(1)故障转移时,判断一个master node是宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题 (2)即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了

目前采用的是sentinal 2版本,sentinal 2相对于sentinal 1来说,重写了很多代码,主要是让故障转移的机制和算法变得更加健壮和简单

2、哨兵的核心知识

(1)哨兵至少需要3个实例,来保证自己的健壮性 (2)哨兵 + redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性 (3)对于哨兵 + redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练

3、为什么redis哨兵集群只有2个节点无法正常工作?

哨兵集群必须部署2个以上节点

如果哨兵集群仅仅部署了个2个哨兵实例,quorum=1

+----+         +----+ | M1 |---------| R1 | | S1 |         | S2 | +----+         +----+

Configuration: quorum = 1

master宕机,s1和s2中只要有1个哨兵认为master宕机就可以还行切换,同时s1和s2中会选举出一个哨兵来执行故障转移

同时这个时候,需要majority,也就是大多数哨兵都是运行的,2个哨兵的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=2),2个哨兵都运行着,就可以允许执行故障转移

但是如果整个M1和S1运行的机器宕机了,那么哨兵只有1个了,此时就没有majority来允许执行故障转移,虽然另外一台机器还有一个R1,但是故障转移不会执行

4、经典的3节点哨兵集群

       +----+        | M1 |        | S1 |        +----+           | +----+    |    +----+ | R2 |----+----| R3 | | S2 |         | S3 | +----+         +----+

Configuration: quorum = 2,majority

如果M1所在机器宕机了,那么三个哨兵还剩下2个,S2和S3可以一致认为master宕机,然后选举出一个来执行故障转移

同时3个哨兵的majority是2,所以还剩下的2个哨兵运行着,就可以允许执行故障转移

 

哨兵模式底层原理

1、sdown和odown转换机制

sdown和odown两种失败状态

sdown是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机

odown是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机

sdown达成的条件很简单,如果一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机

sdown到odown转换的条件很简单,如果一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵也认为那个master是sdown了,那么就认为是odown了,客观认为master宕机

2、哨兵集群的自动发现机制

哨兵互相之间的发现,是通过redis的pub/sub系统实现的,每个哨兵都会往__sentinel__:hello这个channel里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在

每隔两秒钟,每个哨兵都会往自己监控的某个master+slaves对应的__sentinel__:hello channel里发送一个消息,内容是自己的host、ip和runid还有对这个master的监控配置

每个哨兵也会去监听自己监控的每个master+slaves对应的__sentinel__:hello channel,然后去感知到同样在监听这个master+slaves的其他哨兵的存在

每个哨兵还会跟其他哨兵交换对master的监控配置,互相进行监控配置的同步

3、slave配置的自动纠正

哨兵会负责自动纠正slave的一些配置,比如slave如果要成为潜在的master候选人,哨兵会确保slave在复制现有master的数据; 如果slave连接到了一个错误的master上,比如故障转移之后,那么哨兵会确保它们连接到正确的master上

4、slave->master选举算法

如果一个master被认为odown了,而且majority哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个slave来

会考虑slave的一些信息

(1)跟master断开连接的时长 (2)slave优先级 (3)复制offset (4)run id

如果一个slave跟master断开连接已经超过了down-after-milliseconds的10倍,外加master宕机的时长,那么slave就被认为不适合选举为master

(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state

接下来会对slave进行排序

(1)按照slave优先级进行排序,slave priority越低,优先级就越高 (2)如果slave priority相同,那么看replica offset,哪个slave复制了越多的数据,offset越靠后,优先级就越高 (3)如果上面两个条件都相同,那么选择一个run id比较小的那个slave

5、quorum和majority

每次一个哨兵要做主备切换,首先需要quorum数量的哨兵认为odown,然后选举出一个哨兵来做切换,这个哨兵还得得到majority哨兵的授权,才能正式执行切换

如果quorum < majority,比如5个哨兵,majority就是3,quorum设置为2,那么就3个哨兵授权就可以执行切换

但是如果quorum >= majority,那么必须quorum数量的哨兵都授权,比如5个哨兵,quorum是5,那么必须5个哨兵都同意授权,才能执行切换

6、configuration epoch

哨兵会对一套redis master+slave进行监控,有相应的监控的配置

执行切换的那个哨兵,会从要切换到的新master(salve->master)那里得到一个configuration epoch,这就是一个version号,每次切换的version号都必须是唯一的

如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待failover-timeout时间,然后接替继续执行切换,此时会重新获取一个新的configuration epoch,作为新的version号

7、configuraiton传播

哨兵完成切换之后,会在自己本地更新生成最新的master配置,然后同步给其他的哨兵,就是通过之前说的pub/sub消息机制

这里之前的version号就很重要了,因为各种消息都是通过一个channel去发布和监听的,所以一个哨兵完成一次新的切换之后,新的master配置是跟着新的version号的

其他的哨兵都是根据版本号的大小来更新自己的master配置的

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3