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文档。 <…...
五子棋双人对战项目(2)——登录模块
目录 一、数据库模块 1、创建数据库 2、使用MyBatis连接并操作数据库 编写后端数据库代码 二、约定前后端交互接口 三、后端代码编写 文件路径如下: UserAPI: UserMapper: 四、前端代码 登录页面 login.html: 注册页面…...
几种操作系统和几种cpu
常见的操作系统:windows,linux,macOS,统信,deepin,raspberry,andriod,iOS,鸿蒙,等等。 常见的cpu:intel,amd,龙芯&#x…...
[Cocoa]_[初级]_[使用NSNotificationCenter作为目标观察者实现时需要注意的事项]
场景 在开发Cocoa程序时,由于界面是用Objective-C写的。无法使用C的目标观察者[1]类。如果是使用第二种方案2[2],那么也需要增加一个代理类。那么有没有更省事的办法? 说明 开发界面的时候,经常是需要在子界面里传递数据给主界面࿰…...
彩虹易支付最新版源码及安装教程(修复BUG+新增加订单投诉功能)
该源码当前版本为较新的版本,新增了订单投诉功能和一套精美的二次元模板。 此版本为全开源版本,所有文件均未加密。系统默认安装完成后无法直接打开,需要进一步配置。 本站特别针对BUG文件进行了修复,且在PHP7.4环境下表现良好。…...
ping香港服务器超时的原因通常有哪些?
Ping命令用于测试计算机与目标服务器之间的网络连接。当您在尝试使用ping命令检测服务器时遇到超时的情况,通常可能是由以下原因造成的: 1. 网络连接问题: - 本地网络故障:如网线损坏、路由器故障或配置不当。 - ISP(互联网服务提…...
书生大模型实战(从入门到进阶)L3-彩蛋岛-InternLM 1.8B 模型 Android 端侧部署实践
目录 1 环境准备 1.1 安装rust 1.2 安装Android Studio 1.3 设置环境变量 2 转换模型 2.1 安装mlc-llm 2.2 (可选)转换参数 2.3 (可选)生成配置 2.4 (可选)上传到huggingface 2.5 (可选) 测试转换的模型 3 打包运行 3.1 修改配置文件 3.2 运行打包命令 3.3 创建签…...
setState是同步更新还是异步更新
setState是同步更新还是异步更新 先说结论setState为什么设计为异步react18之前为什么不确定是同步还是异步呢react18之后setState有哪些改动 先说结论 React18之前:使用了ReactDOM.render,setState在React调度流程中是异步更新,在原生事件和…...
TCP 流量控制 - 滑动窗口和拥塞控制算法解析
滑动窗口主要管理数据流动的速率,对单个连接较好,拥塞控制则防止网络出现过载,对提高整体的网络通畅较好。下面详细解析两者的原理和作用。 1. TCP 滑动窗口算法 TCP 使用滑动窗口机制来控制数据的发送和接收,以实现流量控制&…...
MongoDB聚合操作及索引底层原理
目录 链接:https://note.youdao.com/ynoteshare/index.html?id=50fdb657a9b06950fa255a82555b44a6&type=note&_time=1727951783296 本节课的内容: 聚合操作: 聚合管道操作: 编辑 $match 进行文档筛选 编辑 将筛选和投影结合使用: 编辑 多条件匹配: …...
C++ | Leetcode C++题解之第454题四数相加II
题目: 题解: class Solution { public:int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {unordered_map<int, int> countAB;for (int u: A) {for (int v: B) {count…...
手机如何建立网站/网站推广专家十年乐云seo
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 只要一听到 “自动化…...
gbk网站/百度问答官网
我正在努力使用我的Spring Security配置,到目前为止我无法使其工作.我不知道为什么我的自定义PermissionEvaluator没有被调用,我的PreAuthorize注释使用hasPermission表达式被忽略.我正在使用Spring 4.2.4和Spring security 4.1.0她是我的代码:网络安全配置Configur…...
锐旗网站建设/长沙官网seo技巧
实验环境及思路 1.在windows server 2012中安装web服务器,FTP服务 2.启动FTP服务进行上传下载测试 3.启用windows server 防火墙指定被动模式需要开放的端口范围 4.测试服务器与客户端连接,并查看指定的端口范围 备注:本篇文档只做FTP安装及测试操作 …...
政府网站架构/bt磁力搜索引擎在线
结对小伙伴博客链接 20145327高晨 实验报告封面 实验内容、步骤与体会 1、开发环境的配置同实验一 2、将实验代码拷贝到共享文件夹中 3、在虚拟机中编译代码 注:对于多线程相关的代码,编译时需要加-lpthread 的库 4、下载调试 在超级终端中运行可执行文件…...
网站建设服务电话/友情链接分析
电机静态扭矩是什么就是电机转子不动时,保持转子静止状态的力量有多大,换句话说,你用超过这个扭矩的力量去转动转子会使转子转动,否则转子保持不动。静态转矩特性静态转矩特性为步进电机的转子静止状态(平衡状态)的特性࿰…...
江苏做网站的公司/百度秒收录排名软件
首先Apache的Rewite规则差别不是很大,但是Nginx的Rewrite规则比Apache的简单灵活多了Nginx可以用if进行条件匹配,语法规则类似Cif ($http_user_agent ~ MSIE) {rewrite ^(.*)$ /msie/$1 break;} Rewrite的Flags last - 基本上都用这个Flag。 break - 中止R…...