Redis-哨兵
概念
Redis Sentinel 相关名词解释
注意:
- 哨兵机制不负责存储数据,只是对其它的redis-server进程起到监控的作用
- 哨兵节点,也会搞一个集合,防止一个挂了
⼈⼯恢复主节点故障
用户监控:
实际开发中,对于服务器后端开发,监控程序,是很重要的
服务器长期运行,总会有一些意外,具体什么时候出现意外,无法预知,就写一个监控程序,来监控服务器的运行状态
监控程序,往往搭配报警程序
服务器出现状态异常,就触发报警程序,给程序员报警
程序员如何恢复?
1.先看看主节点能不能抢救,好不好抢救
2.如果主节点短时间内难以恢复,就挑一个从节点,设置为新的主节点
a)选中新的主节点,通过slaveof no one自立山头
b)把其他的从节点,修改slaveof发主节点IP port,连上新的主节点
c)告知客户端,让客户端能够连接新的主节点,完成修改操作
当之前挂的主节点,修改好之后,就可以作为一个新的从节点,挂到这组机器中
当然,这个人工干预的做法,十分繁琐
哨兵⾃动恢复主节点故障
当主节点出现故障时,RedisSentinel能⾃动完成故障发现和故障转移,并通知应⽤⽅,从⽽实现 真正的⾼可⽤
Redis Sentinel 架构
这三个哨兵进程会监控现有的redis master和slave
(监控:这些进程之间,会建立tcp长连接,定期发送心跳包)
借助上述的监控机制,就可以及时发现,某个主机是否挂了
如果从节点挂了,无影响
如果主节点挂了,问题就大了,哨兵就要发挥作用了
- 此时,一个哨兵节点发现主节点挂了,不够,需要多个哨兵节点共同认同这件事,防止出现误判
- 主节点确实是挂了,这些哨兵节点,就会推举出一个leader,由这个leader负责从现有的从节点,挑选出一个作为新的主节点
- 挑选出新的主节点之后,哨兵节点,就会自动控制被选中的节点,执行slave no one,并且控制其它从节点,修改slaveof到新的主节点
- 哨兵节点会自动通知客户端程序,告知新的主节点是谁,后续客户端就会针对新的主节点进行写操作了
RedisSentinel核心功能
监控:Sentinel节点会定期检测Redis数据节点、其余哨兵节点是否可达
故障转移:实现从节点晋升(promotion)为主节点并维护后续正确的主从关系
通知:Sentinel节点会将故障转移的结果通知给应⽤⽅
安装部署(基于docker)
引入
这里涉及到六个节点,此时,只有一个云服务器,就在这里完成搭建
由于这些节点很多,相互之间容易打架,依赖的端口号/配置文件/数据文件...
如果直接部署,就需要去避开这些冲突,这种方式比较繁琐
下面用docker去解决上述问题:
docker可以认为是一个"轻量级"的虚拟机,起到了虚拟机这样的的隔离环境的效果,但是又没有吃很多的硬件资源,即使是比较拉跨的云服务器,也能构造出好几个这样的虚拟的环境
docker中关键概念"容器",看作一个轻量级的虚拟机
docker中"镜像"和"容器"的关系,相当于"可执行程序"和"进程"关系
拉取到的镜像,里面包含一个精简的linux操作系统,并且上面会安装redis,只要基于这个镜像创建一个容器跑起来,此时,redis服务器就搭建好了
准备工作
①安装docker和docker-compose
apt install docker-compose
②停⽌之前的redis-server
service redis-server stop
# 停⽌ redis-sentinel 如果已经有的话
service redis-sentinel stop
③ 使⽤docker获取redis镜像
#配置
vim /etc/docker/daemon.json
{
"registry-mirrors":["https://dockerpull.com"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker
docker pull redis:5.0.9
编排redis主从节点
docker-compose进行容器编排
此处涉及多个redis server,也有多个redis哨兵节点
每一个redis server或者每一个redis哨兵节点都是作为一个单独的容器
通过一个配置文件,把具体要创建哪些容器,每个容器运行的各种参数,描述清楚,后续通过一个简单的命令,就能批量的启动/停止这些容器
注意:
redis哨兵节点,有一个也是可以的,也能完全上面的功能
1.如果哨兵节点只要一个,自身是容易出现问题的
2.出现误判的概率比较高
毕竟网络传输是容易出现抖动或者延迟,丢包的,如果只有一个,出现问题的影响就很大
基本原则 :
在分布式系统中,避免"单点"
哨兵节点,最好奇数个,最少3个
使用yml这样的格式来作为配置文件
1)创建三个容器,作为redis的数据节点(一主,两从)
2)创建三个容器,作为redis的哨兵节点
其实也是可以用一个yml文件,直接启动6个容器,但是如果同时启动,可能是哨兵先启动完成,数据节点后启动完成,哨兵可能就会认为数据节点挂了,会影响观察执行日志的过程
version: '3.7'
services:master:image: 'redis:5.0.9'container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: 'redis:5.0.9'container_name: redis-slave1restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6380:6379slave2:image: 'redis:5.0.9'container_name: redis-slave2restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6381:6379
~
docker容器,可以理解成是一个轻量的虚拟机,在这个容器里,端口号和外面宿主机的端口号是两个体系
如果容器外面使用了5000端口,内部也可以使用,彼此不会冲突
三个容器,每个容器内部的端口号都是自成一派的,容器1的6379和2的6379之间是不会有冲突的,可以把两个容器视为两个主机
有的时候,希望在容器外面能够访问到容器里面的端口,就可以把容器内部的端口映射成宿主机的端口,后续防伪码宿主机的这个端口,就相当于在访问在访问对应容器的对应端口
站在宿主的角度,访问上述几个端口的时候,也不知道这个端口实际上一个宿主机的服务,还是来自容器内部的服务,只要正常去使用即可
此处不必写主节点ip,直接写主节点的容器名
容器启动之后,被分配的ip是啥也不知道
容器名类似于域名一样,docker自动进行域名解析,就得到对应的ip
启动所有容器:
docker-compose up -d
查看正在运行的容器:
docker ps -a
编排 redis-sentinel节点
version: '3.7'
services:sentinel1:image: 'redis:5.0.9'container_name: redis-sentinel-1restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel1.conf:/etc/redis/sentinel.confports:- 26379:26379sentinel2:image: 'redis:5.0.9'container_name: redis-sentinel-2restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel2.conf:/etc/redis/sentinel.confports:- 26380:26379sentinel3:image: 'redis:5.0.9'container_name: redis-sentinel-3restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel3.conf:/etc/redis/sentinel.confports:- 26381:26379
哨兵节点,会在运行过程中,对配置文件进行自动的修改
因此,就不能拿一个配置文件,给三个容器分别映射
既然内容相同,为啥要创建多份配置⽂件?
redis-sentinel 在运⾏中可能会对配置进⾏rewrite,修改⽂件内容.
如果⽤⼀份⽂件,就可能出现修改混乱的情况
这里的票数,是为了更稳健的确认,当前的redis-server是否挂了,不能听一个哨兵的一面之词
docker的一个核心功能,能够进行端口的映射,容器内使用什么端口都行,但是映射出去之后,还是要确保端口不能重复
sentinel1:
bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000
sentinel2和sentinel3:
启动所有容器:
查看运⾏⽇志:
此处这个哨兵节点,不认识redis-master
docker-compose一下子启动了N个容器,此时N个容器处于同一个"局域网"中
可以使这个N个容器之间相互访问
三个redis-server节点,是一个局域网
三个哨兵节点,是另一个局域网,是新创建的
默认情况下,这两个网络不互通
解决方案:可以使用docker-compose把此处的两组服务给放到同一个局域网中
互通
docker network ls列出当前docker中的局域网
在docker-compose.yml中加入:
version: '3.7'
services:sentinel1:image: 'redis:5.0.9'container_name: redis-sentinel-1restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel1.conf:/etc/redis/sentinel.confports:- 26379:26379sentinel2:image: 'redis:5.0.9'container_name: redis-sentinel-2restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel2.conf:/etc/redis/sentinel.confports:- 26380:26379sentinel3:image: 'redis:5.0.9'container_name: redis-sentinel-3restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel3.conf:/etc/redis/sentinel.confports:- 26381:26379networks:default:external:name: redis-data_default
此时先把原来的docker停止,重启:
再查看logs,成功:
观察redis-sentinel 的配置rewrite
再次打开哨兵的配置⽂件,发现⽂件内容已经被⾃动修改了
哨兵存在的意义,能够在redis主从结构出现问题的时候,找出一个新的主节点来代替之前挂了的节点,保证整个redis仍然是可用状态
重新选举
下面手动把主节点干掉:
主节点此时就处于退出状态:
查看日志:
此时redis-master挂了
- sdown:主观下线,本哨兵节点,认为该主节点挂了
- odown:客观下线,好几个哨兵都认为该节点挂了,达成一致(法定票数)
此时就需哨兵节点选出一个新的主节点
此时再去连接6379:
无法连接
看6390和6381:
redis-master 重启之后
把刚才挂了的主节点再启动起来:
此时就已经失去主节点的身份了
选举原理
哨兵重新选取主节点的流程
1. 主观下线
哨兵节点通过心跳包,判定redis服务器是否正常工作
如果心跳包没有如约而至,就说明redis服务器挂了
此时还不能排除网络波动的影响,只能单方面认为挂了
2. 客观下线
多个哨兵都认为主节点挂了(法定票数),哨兵就认为这个主节点客观下线
3. 选举出哨兵的leader
要让多个哨兵节点,选出一个leader节点,由这个leader负责选一个从节点作为新的主节点
1号哨兵:
2号哨兵:
2号哨兵立即给自己投了一票:
1号投给了自己:
2,3都投给了2号哨兵
2号就成为了leader
4. leader 挑选出合适的slave成为新的 master
此时leader选举完毕,leader就需要挑选一个从节点,作为新的主节点
1)优先级
每个redis数据节点,都会在配置文件中,有一个优先级的设置
slave-priority默认一样
优先级高的从节点,就会胜出
2)offset
offset最大,就胜出
offset从节点从主节点这边同步数据的进度,数值越大,说明从节点的数据和主节点越接近
3)run id
每个redis节点启动的时候随机生成的一串数字(大小全凭运气)
谁的id⼩,谁上位
新节点指定好之后:
leader就会控制这个从节点,执行slave no one,成为master
再控制其它节点,执行slaveof,让这些其它节点,以新的master作为主节点
总结
- 哨兵节点不能只有⼀个.否则哨兵节点挂了也会影响系统可⽤性.
- 哨兵节点最好是奇数个.⽅便选举leader,得票更容易超过半数.(大部分情况是3个)
- 哨兵节点不负责存储数据.仍然是redis主从节点负责存储.
- 哨兵+主从复制解决的问题是"提⾼可⽤性",不能解决"数据极端情况下写丢失"的问题.
- 哨兵+主从复制不能提⾼数据的存储容量.当我们需要存的数据接近或者超过机器的物理内存,这样 的结构就难以胜任了.为了能存储更多的数据,就引⼊了集群
相关文章:

Redis-哨兵
概念 Redis Sentinel 相关名词解释 注意: 哨兵机制不负责存储数据,只是对其它的redis-server进程起到监控的作用哨兵节点,也会搞一个集合,防止一个挂了 ⼈⼯恢复主节点故障 用户监控: 实际开发中,对于服务器后端开发,监控程序,是很重要的 服务器长期运行,总会有一些意外,…...

Pikachu-Sql-Inject - 基于时间的盲注
基于时间的盲注: 就是前端的基于time 的盲注,什么错误信息都看不到,但是还可以通过特定的输入,判断后台的执行时间,从而确定注入。 mysql 里函数sleep() 是延时的意思,sleep(10)就是数据库延时10 秒返回内…...

JAVA开源项目 旅游管理系统 计算机毕业设计
本文项目编号 T 063 ,文末自助获取源码 \color{red}{T063,文末自助获取源码} T063,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…...

景联文科技入选《2024中国AI大模型产业图谱2.0版》数据集代表厂商
近日,大数据产业领域头部媒体数据猿携手上海大数据联盟联合发布了备受瞩目的《2024中国AI大模型产业图谱2.0版》。以大数据与AI为代表的智能技术为主要视角,聚焦全产业链,为业内提供更为专业直观的行业指导。 景联文科技凭借高质量数据集&…...

【C语言】内存函数的使用和模拟实现
文章目录 一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset的使用四、memcmp的使用 一、memcpy的使用和模拟实现 在之前我们学习了使用和模拟实现strncpy函数,它是一个字符串函数,用来按照给定的字节个数来拷贝字符串,那么问…...

在WPF中实现多语言切换的四种方式
在WPF中有多种方式可以实现多语言,这里提供几种常用的方式。 一、使用XML实现多语言切换 使用XML实现多语言的思路就是使用XML作为绑定的数据源。主要用到XmlDataProvider类. 使用XmlDataProvider.Source属性指定XML文件的路径或通过XmlDataProvider.Document指定…...
30min 的OpenCV learning Note
1.安装python和pycharm与环境搭配 打开Windows终端:(winR)(一般使用清华镜像网站安装库比较快) pip install opencv-contrib-python -i https://pypi.mirrors.ustc.edu.cn/simple 或者 python -m pip install open…...

C--编译和链接见解
欢迎各位看官!如果您觉得这篇文章对您有帮助的话 欢迎您分享给更多人哦 感谢大家的点赞收藏评论 感谢各位看官的支持!!! 一:翻译环境和运行环境 在ANSIIC的任何一种实现中,存在两个不同的环境1,…...
【QT Quick】基础语法:基础类与控件
QML 的基础类和控件中,我们可以看到主要的几个分类:基础控件类、窗口类以及组件类。以下是对这些控件及其属性、继承关系等的详细讲解: 控件关系总结 QtObject 是所有 QML 对象的基类。它定义了基础属性,主要用于逻辑和数据封装…...

使用 SSH 连接 Docker 服务器:IntelliJ IDEA 高效配置与操作指南
使用 SSH 连接 Docker 服务器:IntelliJ IDEA 高效配置与操作指南 本文详细介绍了如何在 2375 端口未开放的情况下,通过 SSH 连接 Docker 服务器并在 Idea 中进行开发。通过修改用户权限、生成密钥对以及配置 SSH 访问,用户可以安全地远程操作…...
Gas费用是什么?
Gas费用是什么? 每5个Byte 需要1个GasGasLimit 用来限制合约最多执行多少次运算GasPrice 每次计算需要支付的费用在Web3的语境中,尤其是在以太坊(Ethereum)这样的区块链平台上,Gas费是一个核心概念。以下是关于Gas费的详细解释: 1. 定义 Gas是以太坊网络上的计算单位,…...
大语言模型(LLM)的子模块拆拆分进行联邦学习;大语言模型按照多头(Multi-Head)拆分进行联邦学习
目录 大语言模型(LLM)的子模块拆拆分进行联邦学习 方式概述 简单示例 大语言模型按照多头(Multi-Head)拆分进行联邦学习 场景设定 多头拆分与联邦学习 示例说明 大语言模型(LLM)的子模块拆拆分进行联邦学习 大语言模型(LLM)的子模块拆分进行联邦学习,主要涉及…...

Qt 概述
1. Qlabel HelloWorld 程序 使用纯代码实现 // widget.cpp Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 给当前这个lable对象,指定一个父对象QLabel* label new QLabel(this);// C语言风格的字符串可以直接…...

移动应用的界面配置-手机银行APP
设置登录界面为线性布局,组件垂直居中排列设置主页为滚动模式,包括布局、添加背景图片设置按钮样式,包括形状、边框线的宽度和颜色 设置登录界面 设置界面为线性布局,组件垂直居中排列 --android:gravity"center_vertical…...

微服务nginx解析部署使用全流程
目录 1、nginx介绍 1、简介 2、反向代理 3、负载均衡 2、安装nginx 1、下载nginx 2、解压nginx安装包 3、安装nginx编辑 1、执行configure命令 2、执行make命令 4、启动nginx 1、查找nginx位置并启动 2、常用命令 3、反向代理 1、介绍反向代理配置 1、基础配置…...

华硕天选笔记本外接音箱没有声音
系列文章目录 文章目录 系列文章目录一.前言二.解决方法第一种方法第二种方法 一.前言 华硕天选笔记本外接音箱没有声音,在插上外接音箱时,系统会自动弹出下图窗口 二.解决方法 第一种方法 在我的电脑上选择 Headphone Speaker Out Headset 这三个选项…...
Unity中Socket_TCP异步连接,加入断线检测以及重连功能
1、服务端 using System; using System.Collections.Generic; using System.Text; #region 命名空间 using System.Net; using System.Net.Sockets; using System.Threading; using UnityEngine; #endregionnamespace AsynServerConsole {/// <summary>/// Tcp协议异步通…...
Android build子系统(01)Ninja构建系统解读
说明:本文将解读Ninja构建系统,这是当前Android Framework中广泛使用的构建工具。我们将从Ninja的起源和背景信息开始,逐步解读Ninja的优势和核心原理,并探讨其一般使用场景。然后介绍其在Android Framework中的应用及相关工具&am…...
徐老师的吉祥数
题目背景 文件读写 输入文件avoid.in 输出文件avoid.out 限制 1000ms 512MB 题目描述 众所周知, 3这个数字在有些时候不是很吉利,因为它谐音为 “散” 所以徐老师认为只要是 3的整数次幂的数字就不吉利 现在徐老师想知道,在某个范围[l,r] …...

使用html写一个能发起请求的登录界面
目录 head部分 内联样式部分 body部分 login-form类的div myModal类的div id script部分 总的代码 界面与操作演示 <!DOCTYPE html> <html lang"en"> <!DOCTYPE html> 这是文档类型声明,告诉浏览器这是一个 HTML文档。 <…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...

【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
深度解析:etcd 在 Milvus 向量数据库中的关键作用
目录 🚀 深度解析:etcd 在 Milvus 向量数据库中的关键作用 💡 什么是 etcd? 🧠 Milvus 架构简介 📦 etcd 在 Milvus 中的核心作用 🔧 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目
应用场景: 1、常规某个机器被钓鱼后门攻击后,我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后,我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...