Redis系列之Redis Sentinel

概述

Redis主从集群,一主多从模式,包括一个Master节点和多个Slave节点。Master负责数据的读写,Slave节点负责数据的查询。Master上收到的数据变更,会同步到Slave节点上实现数据的同步。通过这种架构实现可以Redis的读写分离,提升数据的查询性能。
在这里插入图片描述
主从集群不提供容错和恢复功能,一旦Master节点宕机,不会自动选出新的Master,导致后续客户端所有写请求直接失败。

引入

Redis引入Redis Sentinel,即哨兵机制,哨兵会监控Redis主从集群节点的状态,当Master节点出现故障,会自动从剩余的Slave节点中选择新的Master:

  • 一旦监控发现redis主节点失效,将选举出一个哨兵节点作为领导者;
  • sentinel的领导者从剩余的从redis节点中选出一个redis节点作为新的主redis节点对外服务。

Redis Sentinel用于实现Redis集群的高可用,本身也是分布式的,作为一个哨兵集群去运行,可以监控一个或者多个主从集群:

  • 故障转移时,判断一个Master节点是否宕机,需要大部分的哨兵都同意才行,涉及到分布式选举的问题
  • 即使部分哨兵节点挂掉,哨兵集群还是能正常工作

Redis Sentinel,能够自动完成故障发现和故障转移并通知应用方,具备如下功能:

  • 集群监控:负责监控Master和Slave进程是否正常工作;
  • 消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员;
  • 故障转移:如果Master节点宕机,会自动转移到Slave节点上;
  • 配置中心:如果发生故障转移,通知客户端新的Master地址;

另外

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

安装

安装Redis Sentinel之前,需要确保已经成功安装至少一套Redis主从集群,即集群启动成功。生产环境里,Redis主从集群节点和Redis Sentinel集群节点最好是不同的IP节点。为了满足过半原则,Redis Sentinel至少需要3台节点。

安装时,提前创建好sentinel运行时需要的几个文件夹:conf、data、log,以及sentinel.conf配置文件,仅供参考:

port 26379
daemonize yes
logfile "26379.log"
# Sentinel实例的目录
dir "/data/redis/sentinel/"
# 格式:sentinel [option_name] [master_name] [ip] [port] [quorum],sentinel监控的master为mymaster,最后的2表示当集群中有2个sentinel认为master不可用时,才真正认为该master不可用,即客观下线
sentinel monitor mymaster 10.215.20.7 6379 2
# sentinel会向master发送心跳PING来确认master是否存活,如果master在down-after-milliseconds内不回应PONG或回复错误消息,则这个sentinel会主观地认为这个master不可用
sentinel down-after-milliseconds master 30000
# 在发生failover主备切换时,指定最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为1来保证每次只有一个slave处于不能处理命令请求的状态
sentinel parallel-syncs mymaster 1
# failover过期时间,当failover开始后,在此时间内仍然没有触发任何failover操作,当前sentinel将会认为此次failoer失败,单位为秒
sentinel failover-timeout mymaster 180000

以Redis用户执行启动命令:sudo -u redis /opt/redis/bin/redis-sentinel /data/redis/sentinel/conf/sentinel.conf,从启动日志可判断Sentinel集群是否正常启动。

在节点执行info sentinel命令,查看sentinel的信息。

心跳检查

Sentinel通过三个定时任务来检测各个节点是否存活及出现超时:

  1. 每隔10秒,每个哨兵节点会向已知的主从节点发送info命令获取最新的主从架构。哨兵节点通过解析响应信息,获取当前Redis数据节点的最新拓扑结构。如果是新增节点,哨兵就会与其建立连接;
  2. 每隔2秒,哨兵节点都会向主从节点的__sentinel__:hello频道发送自己的信息。两个目的:
    • 发现新的哨兵节点
    • 哨兵节点之间交换主节点的状态,作为后面客观下线以及领导者选择的依据
  3. 每隔1秒,哨兵会给每个主从节点、其他哨兵节点发送PING命令。此定时任务是哨兵心跳机制中的核心,它涉及到Redis数据节点的运行状态监控,哨兵领导者的选举等细节操作。当哨兵节点发送PING命令后,若超过down-after-milliseconds后,没有收到有效回复(错误的回复不是有效回复),当前哨兵节点会认为该节点主观下线。

发送的消息内容格式为:
<哨兵地址>,<哨兵端口>,<哨兵运行ID>,<哨兵配置版本>,<主数据库名称>,<主库地址>,<主库端口>,<主库配置版本>

自动发现机制

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

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

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

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

Slave配置的自动纠正

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

下线

有主观下线和客观下线两种。

主观下线

Subjectively Down,缩写sdown,也叫主观宕机。

在第三个定时任务中,每隔1秒哨兵节点会向每个Redis数据节点发送PING命令,若超过down-after-milliseconds设定的时间没有收到响应,则会对该节点做失败判定,这种行为叫做主观下线。是某一个哨兵节点的判断,存在误判概率。

客观下线

Objectively Down,缩写sdown,也叫客观宕机。

当哨兵节点判定一个主节点为主观下线后,则会通过sentinelis-master-down-by-addr命令询问其他哨兵节点对该主节点的状态,当收到quorunm个其他哨兵节点认为主节点也存在问题的应答后,这时该哨兵节点会对主节点做客观下线的决定。

客观下线是针对主机节点,如果主观下线的是从节点或者其他哨兵节点,则不会进行后面的客观下线和故障转移。

哨兵选举

当主节点客观下线时,需要选举出一个哨兵节点做为领导者,以完成后续选出新的主节点的工作。基于Raft算法的哨兵选举的主要流程:

  1. 每一个做主观下线的哨兵节点都有成为领导者的可能,他们会向其他哨兵节点发送sentinel is-master-down-by addr,要求将它设置为领导者;
  2. 每个哨兵节点在收到一个sentinel is-master-down-by addr命令时,只允许给第一个节点投票,其他节点的该命令都会被拒绝;
  3. 如果某个哨兵节点收到半数以上的同意票,则成为哨兵领导者;
  4. 如果该过程有多个哨兵成为领导者,则将等待一段时间重新进行下一轮选举,直到有且只有一个哨兵节点成为领导者为止;

一般来说,哨兵选举的过程很快,谁先完成客观下线,一般就能成为领导者。

配置传播:哨兵完成切换之后,会在自己本地更新生成最新的Master配置,并更新Version版本号,同步给其他哨兵,通过pub/sub消息机制。

故障转移

Failover,也叫故障切换。

不管是Redis Master还是Slave节点,都必须在配置中指定一个Slave优先级。如果某个Slave优先级配置为0,则永远不会被选为Master,但依然会从Master那里复制数据。

如果一个Master被认为客观下线,且majority数量的哨兵都允许主备切换,则某个哨兵就会执行主备切换操作,此时首先要选举Slave作为Master,会考虑Slave的一些信息:

  • 过滤掉不健康的Slave节点(主观下线、断线)、5秒内没有回复过哨兵节点PING响应的Slave节点
  • 跟Master断开连接的时长
  • Slave优先级
  • 复制offset
  • Run ID

如果一个Slave跟Master断开连接的时间已经超过down-after-milliseconds的10倍,外加Master宕机的时长,则此Slave节点就被认为不适合选举为Master:(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state

接下来会对Slave进行排序:

  • 按照Slave优先级进行排序,Slave节点配置的priority越低,优先级越高;
  • 如果Slave节点priority相同,则看复制offset,哪个Slave复制越多的数据,即offset越靠后(数据越完整,此处注意存在数据丢失可能性),优先级就越高;
  • 如果上面两个条件都相同,则选择一个Run ID较小的那个Slave;

当某个哨兵节点通过选举成为领导者,就要承担起故障转移的工作,具体步骤:

  1. 从从节点列表中选择一个节点作为新的主节点
  2. 在新的主节点上执行slaveof no one,让其变成主节点
  3. 向剩余的从节点发送slaveof命令,让它们成为新主节点的从节点
  4. 哨兵节点集合会将原来的主节点更新为从节点,当其恢复之后命令它去复制新的主节点的数据

缺点

Redis Sentinel集群存在的缺点:

  • 配置复杂性:Redis Sentinel集群相对复杂,需要细致的配置和调优,尤其是在大型集群中;
  • 一致性问题:在网络分区或某些情况下,可能会出现脑裂问题,即集群中的一部分认为主节点是可用的,而另一部分认为主节点已经失效,导致多个主节点同时存在;
  • 故障检测延迟:Sentinel对主节点故障的检测和恢复有一定延迟,可能会在检测到故障和完成故障转移之间有一段时间的服务中断;
  • 有限的高可用性:Sentinel集群本身也可能出现故障,特别是在网络环境不稳定时;
  • 主从复制延迟:从节点的数据同步是异步的,在主节点故障转移过程中,可能会有数据丢失或不一致的情况;
  • 资源开销:搭建Sentinel集群需要额外的资源,且每个Sentinel实例都会定期对Redis节点进行健康检查,增加一定的网络和计算开销;
  • 对网络环境依赖高:Sentinel集群对网络环境要求较高,网络延迟和抖动可能会影响Sentinel的故障检测和选举过程,进而影响故障转移的效率和准确性;
  • 手动干预需求:尽管Sentinel提供自动故障转移功能,但在某些复杂情况下,仍然可能需要人工干预来解决问题,如在处理脑裂情况或调整集群配置时。

数据丢失

此处对上面提到的数据丢失加以详述。Redis哨兵主备切换过程中可能会导致数据丢失的的两种情况:

  • 异步复制:从Master到Slave的复制是异步的,可能有部分数据还没复制到Slave,Master宕机,这部分数据可能发生丢失
    在这里插入图片描述
  • 脑裂:Master节点突然脱离正常的网络,跟其他Slave机器不能连接,但实际上Master还在运行。此时哨兵可能会认为Master宕机并开启选举,将其他Slave切换成Master。此时集群里就会有两个Master,即所谓的脑裂。此时虽然某个Slave被切换成Master,但客户端可能还没来得及切换到新的Master,继续向旧Master写数据。因此旧Master再次恢复时,会被作为一个Slave挂到新的Master上去,自己的数据会清空,重新从新的Master复制数据。而新Master并没有客户端写入的这一部分数据,发生数据丢失。

优化方案

做如下配置:

# 至少有1个Slave
min-slaves-to-write 1
# 数据复制和同步的延迟不能超过10秒
min-slaves-max-lag 10

如果说一旦所有的Slave,数据复制和同步的延迟都超过10秒钟,此时Master就不会再接收任何请求。显然,这个做法并不好,会阻塞客户端提交的写请求。

  • 减少异步复制数据的丢失
    min-slaves-max-lag配置可以确保,一旦Slave复制数据和ack延时太长,就认为可能Master宕机后损失的数据太多,那么就拒绝写请求,这样可以把Master宕机时由于部分数据未同步到Slave导致的数据丢失降低的可控范围内。

  • 减少脑裂的数据丢失
    如果一个Master出现脑裂,跟其他Slave丢失连接,那么上面两个配置可以确保说,如果不能继续给指定数量的Slave发送数据,而且Slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求。因此在脑裂场景下,最多就丢失10秒的数据。

但是在线扩容的问题还是没有解决。

参考

  • Redis哨兵的详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/392999.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工具|阅读PDF时鼠标显示为小手中有向下箭头解决方法

由于工作中&#xff0c;会大量阅读PDF文档&#xff0c;如手册&#xff0c;规格书&#xff0c;各种图纸等&#xff0c;因此好用的PDF工具必不可少。我主要习惯用福昕阅读器&#xff0c;标注比较方便。 所以&#xff0c;本文主要以福昕阅读器为主&#xff0c;当然也适用于其他的阅…

Docker Volume(存储卷)

一、认识 1.1 概念 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这意味着&#xff0c;在容器中的这个目录下写入数据时&#xff0c;容器会将内容直接写入到宿主机上与此容器建立了绑定关系的目录 在宿主机上的这个…

实验8-1-6 在数组中查找指定元素

本题要求实现一个在数组中查找指定元素的简单函数。 函数接口定义&#xff1a; int search( int list[], int n, int x );其中list[]是用户传入的数组&#xff1b;n&#xff08;≥0&#xff09;是list[]中元素的个数&#xff1b;x是待查找的元素。如果找到 则函数search返回…

基于Golang实现Kubernetes边车模式

本文介绍了如何基于 Go 语言实现 Kubernetes Sidecar 模式&#xff0c;并通过实际示例演示创建 Golang 实现的微服务服务、Docker 容器化以及在 Kubernetes 上的部署和管理。原文: Sidecar Pattern with Kubernetes and Go[1] 在这篇文章中&#xff0c;我们会介绍 Sidecar 模式…

软件测试学习笔记

测试学习 1. 测试流程2. Bug的提出什么是bugbug 的描述bug 级别 3. 测试用例的设计什么是测试用例测试用例应如何设计基于需求的设计方法等价类边界值场景法正交表法判定表法错误猜测法 4. 自动化测试回归测试自动化分类 5. 安装 webdriver-manager 和 selenium第一个web自动化…

链表List

简介 STL中的List与顺序表vector类似&#xff0c;同样是一种序列式容器&#xff0c;其原型是带头节点的双向循环链表。 List的使用 list中的接口比较多&#xff0c;此处类似&#xff0c;只需要掌握如何正确的使用&#xff0c;然后再去深入研究背后的原理&#xff0c;已达到可…

基于R语言生物信息学大数据分析与绘图

随着高通量测序以及生物信息学的发展&#xff0c;R语言在生物大数据分析以及数据挖掘中发挥着越来越重要的作用。想要成为一名优秀的生物数据分析者与科研团队不可或缺的人才&#xff0c;除了掌握对生物大数据挖掘与分析技能之外&#xff0c;还要具备一定的统计分析能力与SCI论…

CSDN 僵尸粉 机器人

CSDN 僵尸粉 机器人 1. 前言 不知道什么时候开始每天创作2篇就有1500流量爆光&#xff0c;每次都能收获一些关注和收藏&#xff0c;感觉还是挻开心的感觉CSDN人气还是挻可以的以前各把月一个收藏和关注都没有写的动力了。 2. 正文 后面又连接做了2天的每日创建2篇任务&…

JVM(九)深入解析Java字节码技术与执行模型

这篇文章深入探讨了Java字节码技术&#xff0c;包括字节码的简介、获取字节码清单的方法、解读字节码清单、查看class文件中的常量池信息、查看方法信息、线程栈与字节码执行模型、方法体中的字节码解读、对象初始化指令、栈内存操作指令、局部变量表、流程控制指令、算术运算指…

简单的docker学习 第3章 docker镜像

第3章 Docker 镜像 3.1镜像基础 3.1.1 镜像简介 ​ 镜像是一种轻量级、可执行的独立软件包&#xff0c;也可以说是一个精简的操作系统。镜像中包含应用软件及应用软件的运行环境。具体来说镜像包含运行某个软件所需的所有内容&#xff0c;包括代码、库、环境变量和配置文件等…

加密软件中的RSA和ECC的主要区别是什么

在加密软件中&#xff0c;RSA&#xff08;Rivest-Shamir-Adleman&#xff09;和ECC&#xff08;Elliptic Curve Cryptography&#xff0c;椭圆曲线密码学&#xff09;是两种广泛使用的非对称加密算法&#xff0c;它们之间存在多个关键区别。 1. 算法基础 RSA&#xff1a;基于大…

汽车网络安全 -- MAC介绍:CMAC与CBC-MAC不能混为一谈

目录 1.什么是MAC 2.CMAC 3.HMAC 4.小结 1.什么是MAC MAC全称Message authentication code&#xff0c;是经过特定算法后产生的一小段数据信息&#xff0c;用于校验某数据的完整性和真实性。在数据传递过程中&#xff0c;可检查其内容是否被更改过&#xff0c;不管更改的原…

Webpack入门基础知识及案例

webpack相信大家都已经不陌生了&#xff0c;应用程序的静态模块打包工具。前面我们总结了vue&#xff0c;react入门基础知识&#xff0c;也分别做了vue3的实战小案例&#xff0c;react的实战案例&#xff0c;那么我们如何使用webpack对项目进行模块化打包呢&#xff1f; 话不多…

路由器IP互联无线对讲系统解决方案

一、项目概况 随着信息化的全面深入发展&#xff0c;各行各业的通信需求日益增长&#xff0c;传统的通信方式无法满足跨网络、跨系统、跨媒介的通信互联互通&#xff0c;打破信息孤岛、提高协同效率&#xff0c;成为当前各行业融合通信的首要任务。尤其大型企业、学校、医院等…

模型优化学习笔记—对比各种梯度下降算法

import mathimport numpy as np from opt_utils import * import matplotlib.pyplot as plt# 标准梯度下降 def update_parameters_with_gd(parameters, grads, learning_rate):L len(parameters) // 2for l in range(1, L 1):parameters[f"W{l}"] parameters[f&q…

自己动手实现scikit库中的fit和transform方法

文本分析第一步要解决的是如何将文本非结构化信息转化为结构化信息&#xff0c;其中最关键的是特征抽取&#xff0c;我们使用scikit-learn库fit和tranform方法实现了文本数据的特征抽取。 但是对于fit和transform&#xff0c;大家可能还是有点迷糊。最近又将《Applied Text An…

如何用一个以太网回环短接器激活以太网接口:以太网短接口制作

在非常特殊的情况下&#xff0c;我们需要在没有接以太网的情况下&#xff0c;使用本地的以太网&#xff08;有些程序、代码必须上网才能运行&#xff09;。这时候需要插上一个以太网短接口&#xff0c;骗系统已经插上网线。 制作以太网短接口 以太网短接口的制作非常简单&…

Linux OS:基于阻塞队列的生产者消费者模型

Linux OS&#xff1a;基于阻塞队列的生产者消费者模型 前言一、阻塞队列的大致框架二、生产者向阻塞队列中生产数据三、消费者获取阻塞队列中数据四、总体生产和消费思路及测试代码4.1 单生产单消费4.2 多生产多消费 五、所以代码 前言 阻塞队列是一种常用于实现生产者消费者模…

低代码: 系统开发准备之确定一般开发流程,需求分析,复杂度分析,标准开发流程

概述 低代码系统开发之前&#xff0c;我们首先要进行一些准备我们首先知道我们软件开发的一般流程同时&#xff0c;我们还要知道&#xff0c;我们整个系统平台的需求如何之后&#xff0c;我们要基于需求进行设计&#xff0c;包含UI设计与系统架构设计 一般开发流程 系统开发…

电路中电阻,电容和电感作用总结

电阻作用 1&#xff0c;上拉电阻 电阻的连接一般是一端接上拉的电源&#xff08;一般与芯片信号的电压值相匹配&#xff09;&#xff0c;另一端连接芯片引脚所对应的信号大概如下图 功能&#xff1a;一、预置某些引脚的功能&#xff0c;例如复位信号拉高&#xff08;失能&…