首页 > 数据库 >Redis 高可用 —— 哨兵

Redis 高可用 —— 哨兵

时间:2023-07-05 17:55:34浏览次数:40  
标签:可用 新主 Redis 主从 故障 哨兵 下线 节点

参考

码哥字节:https://xie.infoq.cn/article/1c714709d00b2b55e8416fb99

小林coding: https://xiaolincoding.com/redis/cluster/sentinel.html

锦鱼不忘旧时晨:https://blog.csdn.net/weixin_44324174/article/details/108939199?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-6-108939199-blog-81585776.235%5Ev38%5Epc_relevant_sort_base2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-6-108939199-blog-81585776.235%5Ev38%5Epc_relevant_sort_base2&utm_relevant_index=13

为什么要有哨兵?

在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点(master)挂了,那么将没有主节点来服务客户端的写操作请求,也没有主节点给从节点(slave)进行数据同步了。

这时如果要恢复服务的话,需要人工介入:

  1. 选择一个「从节点」切换为「主节点」
  2. 让其他从节点指向新的主节点
  3. 通知上游那些连接 Redis 主节点的客户端,将其配置中的主节点 IP 地址更新为「新主节点」的 IP 地址。

这样也不太“智能”了,要是 有一个节点能监控「主节点」的状态,当发现主节点挂了 ,它自动将一个「从节点」切换为「主节点」的话,那么可以节省我们很多事情啊!

Redis 在 2.8 版本以后提供的 哨兵(Sentinel)机制,它的作用是实现 主从节点故障转移。它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。

哨兵节点主要负责三件事情:监控、选主、通知

如何判断主节点真的故障了?(监控)

哨兵会每隔 1 秒给所有主从节点发送 PING 命令,当主从节点收到 PING 命令后,会发送一个响应命令给哨兵,这样就可以判断它们是否在正常运行。

如果主节点或者从节点没有在规定的时间内响应哨兵的 PING 命令,哨兵就会将它们标记为「主观下线」。这个「规定的时间」是配置项 down-after-milliseconds 参数设定的,单位是毫秒

那什么是客观下线?

哨兵在部署的时候不会只部署一个节点,而是用多个节点部署成哨兵集群最少需要三台机器来部署哨兵集群),通过多个哨兵节点一起判断,就可以就可以避免单个哨兵因为自身网络状况不好,而误判主节点下线的情况。

当一个哨兵判断主节点为「主观下线」后,就会向其他哨兵发起 is-master-down-by-addr 命令,其他哨兵收到这个命令后,就会根据自身和主节点的网络状况,做出赞成投票或者拒绝投票的响应。

当这个哨兵的赞同票数达到哨兵配置文件中的 quorum (这里不需要过半)配置项设定的值后,这时主节点就会被该哨兵标记为「客观下线」。

PS:quorum 的值一般设置为哨兵个数的二分之一加1,例如 3 个哨兵就设置 2。

哨兵判断完主节点客观下线后,哨兵就要开始在多个「从节点」中,选出一个从节点来做新主节点。

 

哨兵选主

由哪个哨兵作为 Leader 来进行主从故障转移?

哨兵的选举采用的是Raft算法,Raft是一个用户管理日志一致性的协议,它将分布式一致性问题分解为多个子问题:Leader选举、日志复制、安全性、日志压缩等。Raft将系统中的角色分为领导者(Leader)、跟从者(Follower)和候选者(Candidate).......

大致简单过程

  1. 每个做主观下线的sentinel节点像其他sentinel节点发送命令,要求将自己设置为领导者
  2. 接收到的sentinel可以同意或者拒绝
  3. 如果该sentinel节点发现自己的 (1)票数已经超过半数 并且 (2)超过了quorum
  4. 如果此过程选举出了多个领导者,那么将等待一段时重新进行选举

为什么哨兵节点至少要有 3 个?

只有 2 个哨兵节点,此时如果一个哨兵想要成功成为 Leader,必须过半,也就是说得获得 2 票,而不是 1 票。如果哨兵集群中有个哨兵挂掉了,那么就只剩一个哨兵了,如果这个哨兵想要成为 Leader,这时票数就没办法达到 2 票,就无法成功成为 Leader,这时是无法进行主从节点切换的。

因此,通常我们至少会配置 3 个哨兵节点。这时,如果哨兵集群中有个哨兵挂掉了,那么还剩下两个个哨兵,如果这个哨兵想要成为 Leader,这时还是有机会达到 2 票的,所以还是可以选举成功的,不会导致无法进行主从节点切换。

Redis 1 主 4 从,5 个哨兵 :

  • quorum 设置为 2,如果 2 个哨兵故障,当主节点宕机时,如果有 3 个哨兵故障的话。此时哨兵集群还是可以判定主节点为“客观下线”(投票可以超过 quorum),但是哨兵不能完成主从切换(但是票数不可以过半)。所以既然怎么样都不能完成主从切换的话(怎么样都不能过半),判定为客观下线相当于是做了无用功。
  • quorum 设置为 3,如果 2 个哨兵故障,当主节点宕机时,如果有 3 个哨兵故障的话。此时哨兵集群不可以判定主节点为“客观下线”,也不能完成主从切换。

所以,quorum 的值建议设置为哨兵个数的二分之一加1,例如 3 个哨兵就设置 2,5 个哨兵设置为 3,而且哨兵节点的数量应该是奇数。

 

主节点故障如何进行主从切换?

主从故障转移操作包含以下四个步骤:

  • 第一步:在已下线主节点(旧主节点)属下的所有「从节点」里面,挑选出一个从节点,并将其转换为主节点。
  • 第二步:让已下线主节点属下的所有「从节点」修改复制目标,修改为复制「新主节点」;
  • 第三步:将新主节点的 IP 地址和信息,通过「发布者/订阅者机制」通知给客户端;
  • 第四步:继续监视旧主节点,当这个旧主节点重新上线时,将它设置为新主节点的从节点;

步骤一:从故障主节点的从节点中选出新的主节点

首先过滤掉网络状况不好的从库:

  • 从库当前在线状态,下线的直接丢弃;

  • 评估之前的网络连接状态 down-after-milliseconds * 10:如果从库总是和主库断连,而且断连次数超出了一定的阈值(10 次),我们就有理由相信,这个从库的网络状况并不是太好,就可以把这个从库筛掉了。

然后进行几轮评估:

  1. 有个叫 slave-priority 配置项,可以给从节点设置优先级。每一台从节点的服务器配置不一定是相同的,我们可以根据服务器性能配置来设置从节点的优先级。
  2. 如果 1 同,比较谁的复制进度更接近之前的主节点,即 某个从节点的 slave_repl_offset 最接近之前主节点的 master_repl_offset
  3. 如果 2 同,比较用来唯一标识从节点的 ID 号

在选举出从节点后,哨兵 leader 向被选中的从节点发送 SLAVEOF no one 命令,让这个从节点解除从节点的身份,将其变为新主节点。

在发送 SLAVEOF no one 命令之后,哨兵 leader 会以每秒一次的频率向被升级的从节点发送 INFO 命令(没进行故障转移之前,INFO 命令的频率是每十秒一次),并观察命令回复中的角色信息,当被升级节点的角色信息从原来的 slave 变为 master 时,哨兵 leader 就知道被选中的从节点已经顺利升级为主节点了。

步骤二:将其余从节点指向新主节点

哨兵 leader 向其余所有从节点发送 SLAVEOF ,让它们成为新主节点的从节点。

通过 Redis 的发布者/订阅者机制来实现的。每个哨兵节点提供发布者/订阅者机制,客户端可以从哨兵订阅消息。

 

标签:可用,新主,Redis,主从,故障,哨兵,下线,节点
From: https://www.cnblogs.com/suBlog/p/17464167.html

相关文章

  • php中执行redis的布隆过滤器的代码
    <?php//测试redis布隆过滤器$redis=newRedis();$redis->connect('127.0.0.1',6379);//创建一个容量是1千万,布隆过滤器://$redis->rawCommand('BF.RESERVE','nzc:redisbloom3','0.0001','10000000');//向布隆过滤器中添加元素:/......
  • redis用docker 部署主从
    dockerpullrediscd/home/softmkdir-predis/configmkdir-predis/data/data6379redis/data/data6380redis/data/data6381cd/home/soft/redis/configviredis6379.conf:port6379viredis6380.conf:#节点容器端口port6380#宿主机ip、master端口replicaof192.168.1......
  • Redis集群、部署Redis集群
    Redis集群集群概述所谓集群,就是通过添加服务器的数量,提供相同的服务,从而让服务器达到一个稳定、高效的状态单个redis存在不稳定性。当redis服务宕机了,就没有可用的服务了单个redis的读写能力是有限的Redis集群是为了强化redis的读写能力redis集群中,每一个redis称之为一个......
  • Redis 6.0 新特性-多线程连环13问!
    导读:支持多线程的Redis6.0版本于2020-05-02终于发布了,为什么Redis忽然要支持多线程?如何开启多线程?开启后性能提升效果如何?线程数量该如何设置?开启多线程后会不会有线程安全问题?多线程的实现原理是怎样的?带着这些疑问,我们来开启Redis新特性-多线程连环13问。 imageRedis......
  • 基于Redis分布式缓存
    1.安装包使用Redis分布式缓存需要安装Redis的支持包,可以通过nuget命令安装,如下:install-packageMicrosoft.Extensions.Caching.StackExchangeRedis 2.在Program.cs文件中注册builder.Services.AddStackExchangeRedisCache(option=>{option.Configuration......
  • .Net下验证MongoDB 的 Linq 模式联合查询是否可用
    MongoDB.Driver类库提供了Linq查询的支持。然而,在使用Linq进行联合查询时,是否能够正确转换为MongoDB底层的查询语句还有待验证。今天,我将进行实验来验证一下。输出查询语句首先,通过订阅MongoClientSettings的功能,将查询语句输出。varsettings=MongoCli......
  • vue 基于 CountUp.js,可用于创建显示数字数据的动画。
    地址:https://github.com/xlsdg/vue-countup-v2Installation$npminstall--savecountup.jsvue-countup-v2Usage<template><divclass="iCountUp"><ICountUp:delay="delay":endVal="endVal"......
  • linux安装redis3.0
    linux安装redis3.01.把下载好的redis压缩包上传至app 解压完成之后,修改成redis文件夹 2.进入redis文件夹进行编译和安装cd /usr/local/redismakemakePREFIX=/usr/local/redisinstall/usr/local/redis目录下出现bin目录就是安装成功 3.修改配置文件可以修改端口......
  • java限流-基于redis+lua
    redis是线程安全的,天然具有线程安全的特性,支持原子性操作,限流服务不仅需要承接超高QPS,还要保证限流逻辑的执行层面具备线程安全的特性,利用Redis这些特性做限流,既能保证线程安全,也能保证性能。结合上面的流程图,这里梳理出一个整体的实现思路:编写lua脚本,指定入参的限流规则,比如对......
  • redis实现延迟任务
    实现思路:发布时间:立即发布、未来要发布list存立即发布,redis中的list是双向链表,方便添加查找性能较高。zset可以去重、排序,存储未来要发布的。 为什么要把任务存储到数据库中?延迟任务是一个通用的服务,任何有延迟需求的任务都可以调用该服务,内存数据库的存储是有限的,需要考虑......