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文档。 <…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...