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文档。 <…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...

PH热榜 | 2025-06-08
1. Thiings 标语:一套超过1900个免费AI生成的3D图标集合 介绍:Thiings是一个不断扩展的免费AI生成3D图标库,目前已有超过1900个图标。你可以按照主题浏览,生成自己的图标,或者下载整个图标集。所有图标都可以在个人或…...