Redis:哨兵(sentinel)

redis:持久化
redis:主从复制
redis:哨兵
redis:集群

它由两部分组成,哨兵节点和数据节点:

  • 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
  • 数据节点:主节点和从节点都是数据节点。

2 部署

2.1 部署主从节点

在上一篇文章中已经写过部署主从节点,使用主从复制。

redis主从节点部署

2.2 部署sentinel节点

哨兵节点本质上是特殊的Redis节点。

3个哨兵节点的配置几乎是完全一样的,主要区别在于端口 的不同(26379/26380/26381),下面以26379节点为例介绍节点的配置和启动方式;

其中,sentinel monitor mymaster 192.168.92.128 6379 2 配置的含义是:该哨兵节点监控192.168.92.128:6379这个主节点,该主节点的名称是mymaster(自己配置的),最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。

sentinel auth-pass mymaster 密码 配置的含义是:如果主节点有密码需要在此配置密码。

此时在看sentinel的配置文件,以端口为26379的配置文件为例:

3.2 使用sentinel专用代码

启动Sentinel的第二个步骤就是将一部分普通的Redis服务器使用的代码替换成Sentinel专用代码。

例如:普通Redis服务器使用redis.c/redisCommandTable作为服务器的命令表:

这也说明了为什么在Sentinel模式下,Redis服务器不能执行set,eval等命令,因为命令表中没有载入这些命令。

3.3 初始化Sentinel状态

接下来,服务器会初始化sentinel.c/sentinelState结构(叫做,Sentinel状态),这个结构保存了服务器所有和Sentinel功能有关的状态。

3.4 初始化Sentinel状态的master属性

初始化Sentinel状态的masters属性。Sentinel状态中的masters字典记录了所有被Sentinel监视的主服务器的相关信息,其中:

字典的键是被监视主服务器的名字。
而字典的值则是被监视主服务器对应的sentinel. c/ sentinelRedisInstance结构。

每个sentinelRedisInstance结构( 后面简称“实例结构”)代表一个被Sentinel监视
的Redis服务器实例( instance),这个实例可以是主服务器、从服务器,或者另外一个Sentinel。

3.5 创建连向主服务器的 络连接

初始化Sentinel的最后一步是创建连向被监视服务器的 络连接,Sentinel将成为主服务器的客户端,他可以向主服务器发送命令,并从命令恢复中获取相关信息。

创建两个连向主服务器的异步 络连接:

  1. 一个是命令连接,用于向主服务器发送命令,并接受命令回复。
  2. 一个是订阅连接,这个链接专门用于订阅主服务器的_sentinel_:hello频道。

为什么有两个连接strong>
在Redis目前的发布与订阅功能中,被发送的信息都不会保存在Redis服务器里面,如果在信息发送时,想要接收信息的客户端不在线或者断线,那么这个客户端就会丢失这条信息。因此,为了不丢失_ sentine1__ :he1lo 频道的任何信息,Sentinel 必须专门用一个订阅连接来接收该频道的信息。

另一方面,除了订阅频道之外,Sentinel 还必须向主服务器发送命令,以此来与主服务器进行通信,所以Sentinel还必须向主服务器创建命令连接。

因为Sentinel需要与多个实例创建多个 络连接,所以Sentinel 使用的是异步连接。

4 基本原理

4.1 发送info信息

4.1.1 向主服务器发送

Sentinel默认会以每10秒一次的频率,通过命令连接向被监视的主服务器发送INFO命令,并通过分析INFO命令的回复来获取主服务器的当前信息。

通过分析主服务器返回的INFO命令回复,Sentinel可以获取两方面的信息:

  1. 关于主服务器本身的信息,包括run_id域记录的服务器运行ID,以及role域记录的服务器角色
  2. 关于主服务器下属的所有从服务器信息,每个从服务器都由一个“slave”字符串开头的行记录,每行的ip=域记录了从服务器的IP地址,而port=域记录从服务器端口,根据这些sentinel无须用户提供从服务器的地址信息,就可以自动发现从服务器。

4.1.2 向从服务发送

当Sentinel发现主服务器有新的从服务器出现时,Sentinel会为这个新的从服务器创建相应的实例结构(实例结构保存在主服务器的实例结构中),Sentinel还会创建连接到从服务器的命令连接和订阅连接。

获取到信息,Sentinel会对保存的从服务器实例结构更新。

4.2 发送publish信息

在默认情况下,Sentinel会以每两秒一次的频率,通过命令连接向所有被监视的主服务器和从服务器发送以下格式的命令:

Sentinel之间不会创建订阅连接

Sentinel在连接主服务器或者从服务器时,会同时创建命令连接和订阅连接,但是在连接其他Sentinel时,却只会创建命令连接,而不创建订阅连接。这是因为Sentinel需要通过接收主服务器或者从服务器发来的频道信息来发现未知的新Sentinel,所以才需要建立订阅连接,而相互已知的Sentinel只要使用命令连接来进行通信就足够了。

4.4 检测服务器状态

4.4.1 检测主观下线状态

在默认情况下,Sentinel会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器,从服务器,其他Sentinel在内)发送PING命令,并通过实例返回的PING命令回复来判断实例是否在线。

实例对PING命令的回复可以分为以下两种情况:

  1. 有效回复:实例返回+PONG,-LOADING,-MASTERDOWN三种回复的其中一种。
  2. 无效回复:返回除以上三种之外的信息或者在指定时限中没有返回任何回复。

Sentinel配置文件中的down-after-milliseconds选项指定了Sentinel判断实例进入主观下线所需的时间长度:如果一个实例在down-after-millsecods毫秒内,连续向Sentinel返回无效回复,那么Sentinel会修改这个实例所对应的实例结构,在结构的flags属性中打开SRI_S_DOWN标识,以此来表示这个实例已经进入主观下线状态。

这个选项不仅作为监视的主服务器的判断主观下线状态,也是主服务器的从服务器,以及其他的Sentinel判断下线的状态。

4.4.2 检查客观下线状态

需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。

当Sentinel 将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这一主服务器的其他Sentinel进行询问,看它们是否也认为主服务器已经进入了下线状态(可以是主观下线或者客观下线)。当Sentinel从其他Sentinel那里接收到足够数量(这个数量是在Sentinel中配置的)的已下线判断之后,Sentinel 就会将从服务器判定为客观下线,并对主服务器执行故障转移操作。

4.5 选举领头Sentinel

当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头的Sentinel,并由领头Sentinel对下线主服务器执行故障转移操作。

在一次配置纪元中,发现主服务器客观下线的Sentinel会要求其他监视主服务器的Sentinel选举自己为局部领头Sentinel(向其他Sentinel发送信息,最先接收到哪个Sentinel的信息就选举哪个Sentinel为局部领头Sentinel),如果超过所有Sentinel数量的一半,那么就选举成功,配置纪元+1进行领头Sentinel故障转移,如果都没有超过一半,那么配置纪元+1,再次进行选择。

4.6 故障转移

在选举产生出领头Sentinel之后,领头Sentinel将对已下线的主服务器执行故障转移操
作,该操作包含以下三个步骤:

(1) 在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为
主服务器。

故障转移操作第一步 要做的就是在已下线主服务器属下的所有从服务器中,挑选出一个状态良好、数据完整的从服务器,然后向这个从服务器发送SLAVEOF no one命令,将这个从服务器转换为主服务器。

补充:redis设计与实现

image.png

(2)让已下线主服务器属下的所有从服务器改为复制新的主服务器。

当新的主服务器出现之后,领头Sentinel下一步要做的就是,让已下线主服务器属下的所有从服务器去复制新的主服务器,这一动作可以通过向从服务器发送SLAVEOF命令来实现。

(3)将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线
时,它就会成为新的主服务器的从服务器。

故障转移的最后就是,将已下线的主服务器设置为新的主服务器的从服务器。

5 相关配置和实践建议

搬运文档

5.1 相关配置

与哨兵相关的几个配置。

(1) sentinel monitor {masterName} {masterIp} {masterPort} {quorum}

sentinel monitor是哨兵最核心的配置,在前文讲述部署哨兵节点时已说明,其中:masterName指定了主节点名称,masterIp和masterPort指定了主节点地址,quorum是判断主节点客观下线的哨兵数量阈值:当判定主节点下线的哨兵数量达到quorum时,对主节点进行客观下线。建议取值为哨兵数量的一半加1。

(2) sentinel down-after-milliseconds {masterName} {time}

sentinel down-after-milliseconds与主观下线的判断有关:哨兵使用ping命令对其他节点进行心跳检测,如果其他节点超过down-after-milliseconds配置的时间没有回复,哨兵就会将其进行主观下线。该配置对主节点、从节点和哨兵节点的主观下线判定都有效。

down-after-milliseconds的默认值是30000,即30s;可以根据不同的 络环境和应用要求来调整:值越大,对主观下线的判定会越宽松,好处是误判的可能性小,坏处是故障发现和故障转移的时间变长,客户端等待的时间也会变长。例如,如果应用对可用性要求较高,则可以将值适当调小,当故障发生时尽快完成转移;如果 络环境相对较差,可以适当提高该阈值,避免频繁误判。

(3) sentinel parallel-syncs {masterName} {number}

sentinel parallel-syncs与故障转移之后从节点的复制有关:它规定了每次向新的主节点发起复制操作的从节点个数。例如,假设主节点切换完成之后,有3个从节点要向新的主节点发起复制;如果parallel-syncs=1,则从节点会一个一个开始复制;如果parallel-syncs=3,则3个从节点会一起开始复制。

parallel-syncs取值越大,从节点完成复制的时间越快,但是对主节点的 络负载、硬盘负载造成的压力也越大;应根据实际情况设置。例如,如果主节点的负载较低,而从节点对服务可用的要求较高,可以适量增加parallel-syncs取值。parallel-syncs的默认值是1。

(4) sentinel failover-timeout {masterName} {time}

sentinel failover-timeout与故障转移超时的判断有关,但是该参数不是用来判断整个故障转移阶段的超时,而是其几个子阶段的超时,例如如果主节点晋升从节点时间超过timeout,或从节点向新的主节点发起复制操作的时间(不包括复制数据的时间)超过timeout,都会导致故障转移超时失败。

failover-timeout的默认值是180000,即180s;如果超时,则下一次该值会变为原来的2倍。

5.2 实践建议

(1)哨兵节点的数量应不止一个,一方面增加哨兵节点的冗余,避免哨兵本身成为高可用的瓶颈;另一方面减少对下线的误判。此外,这些不同的哨兵节点应部署在不同的物理机上。

(2)哨兵节点的数量应该是奇数,便于哨兵通过投票做出“决策”:领导者选举的决策、客观下线的决策等。

(3)各个哨兵节点的配置应一致,包括硬件、参数等;此外,所有节点都应该使用ntp或类似服务,保证时间准确、一致。

(4)哨兵的配置提供者和通知客户端功能,需要客户端的支持才能实现,如前文所说的Jedis;如果开发者使用的库未提供相应支持,则可能需要开发者自己实现。

(5)当哨兵系统中的节点在docker(或其他可能进行端口映射的软件)中部署时,应特别注意端口映射可能会导致哨兵系统无法正常工作,因为哨兵的工作基于与其他节点的通信,而docker的端口映射可能导致哨兵无法连接到其他节点。例如,哨兵之间互相发现,依赖于它们对外宣称的IP和port,如果某个哨兵A部署在做了端口映射的docker中,那么其他哨兵使用A宣称的port无法连接到A。

6 总结

在主从复制的基础上,哨兵引入了主节点的自动故障转移,进一步提高了Redis的高可用性;但是哨兵的缺陷同样很明显:哨兵无法对从节点进行自动故障转移,在读写分离场景下,从节点故障会导致读服务不可用,需要我们对从节点做额外的监控、切换操作。

此外,哨兵仍然没有解决写操作无法负载均衡、及存储能力受到单机限制的问题;这些问题的解决需要使用集群。

7 参考文档

https://www.cnblogs.com/kismetv/p/9609938.html

redis的设计与实现

文章知识点与官方知识档案匹配,可进一步学习相关知识MySQL入门技能树数据库组成32243 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年1月18日
下一篇 2022年1月18日

相关推荐