2023.1.23 关于 Redis 哨兵模式详解

目录

引言

人工恢复主节点故障

​编辑

主从 + 哨兵模式

Docker 模拟部署哨兵模式

关于端口映射 

展现哨兵机制

哨兵重新选取主节点的流程

哨兵模式注意事项


引言

人工恢复主节点故障

1、正常情况

2、主节点宕机

3、程序员主动恢复

  1. 先看看该主节点还能不能抢救
  2. 如果不好定位主节点是啥原因挂的,或知道原因,但是短时间难以解决,此时便需要挑一个从节点,将其设置为新的主节点

a)将选中的从节点,通过 slaveof no one 命令解除之前的主从关系

b)其他的从节点,通过修改 slaveof 命令,将 ip 和 port 改为新上任的主节点

c)告知客户端(修改客户端配置)让客户端能够连接新的主节点,用来完成修改数据的操作

d)原先挂掉的主节点修好后,将其作为一个新的从节点,挂到这组机器中


小总结:

  • Redis 主从复制模式下,主节点故障后需要进行的人工工作是比较繁琐的
  • 如果这个操作过程如果出错,可能会导致问题愈发严重
  • 通过人工干预的做法,就算程序员第一时间看到了报警信息,第一时间处理,恢复的过程也至少需要 半小时 以上
  • 在这期间,整个 Redis 一直不能进行写操作!

注意:

  • 实际开发过程中,对于服务器后端开发,监控程序是非常重要的!

原因:

  • 服务器需具有高可用性,因为其 7*24 小时不间断运行
  • 服务器长期运行总会有一些 意外,同时我们也难以预料具体啥时候会出现意外
  • 总不可能全靠人工来不间断盯着服务器运行吧!

解决方案:

  • 写一个程序,用监控程序来盯着服务器的运行状态
  • 监控程序用于发现 服务器的运行是否出现状态异常
  • 监控程序往往还需搭配 报警程序 一起使用
  • 给程序员报警,通过短信/电话/邮件/微信/钉钉等,通知程序员该服务器程序出现异常

  • 本文主要详解 Redis 部署方式中的主从 + 哨兵模式

主从 + 哨兵模式

  • 如上图所示,此处提供了多个单独的 redis sentinal 进程
  • 这三个哨兵进程会监控现有的 Redis 主节点 和 从节点

注意点一:

  • 这些进程之间会建立 TCP 长连接,通过长连接定期发送心跳包
  • 借助上述的监控机制,便可以及时发现某个主机是否挂了
  • 如果是从节点挂了 其实没多大关系
  • 如果是主节点挂了,哨兵就要发挥作用了!

具体流程:

  1. 当一个哨兵节点发现主节点挂了时,还不够,还需要多个哨兵节点来共同认定这件事(主要是为了防止误判)
  2. 如果主节点确实挂了,便会在这些哨兵节点中推举出一个 leader,由这个 leader 负责从现有的从节点中挑选一个作为新的主节点
  3. 挑选出新的主节点后,哨兵节点便会自动控制被选中的节点,执行 slaveof no one 命令,并且控制其他从节点修改 slaveof 到新的主节点上
  4. 最后哨兵节点会自动通知客户端程序,告知新的主节点是谁,以便后续客户端再进行写操作时,可直接针对新的主节点进行操作

Redis 哨兵核心功能:

  1. 监控
  2. 自动的故障转移
  3. 通知

注意:

  • 虽然可以仅有一个 Redis 哨兵节点,但是相应也会存在一定问题

1、如果哨兵节点只有一个,它自身也容易出现问题

  • 万一这个哨兵节点挂了,后续 Redis 节点也挂了,此时便无法进行自动恢复了

2、出现误判的概率也比较高

  • 比如 网络传输时容易出现抖动或者延迟丢包等

基本的原则:

  • 在分布式系统中,应该避免使用 单点
  • 哨兵节点,最好搞奇数个,最少也应该是 3 个(选举机制)

Docker 模拟部署哨兵模式

  • 此处我们模拟上图进行部署

  • 按理说,这 6个节点需在 6个不同的服务器主机上
  • 但是此时只能在一个 云服务器上完成此处的部署操作

注意点一:

  • 实际工作中,把上述节点放到一个服务器上是毫无意义的!
  • 当前这么做只是条件有限,我仅买了一个云服务器!

注意点二:

  • 由于这些节点还挺多,相互之间容易打架,比如依赖的端口号、配置文件、数据文件等
  • 如果直接部署的话,便需要小心翼翼地避开这些冲突
  • 十分繁琐的同时也会和在不同主机上部署存在较大差异

解决方案:

  • 使用 docker 便可以有效的解决上述的问题
  • docker 中有一个关键概念 ——> 容器
  • 每个容器可看做一个轻量级的虚拟机

 1、安装 docker 和 docker-compose点击下方链接即可跳转安装)

CentOS7 安装 docker 和 docker-compose


2、停止之前的 Redis 服务器


3、使用 docker 获取 Redis 镜像

  • 此处我们通过下方命令,直接从 docker hub 上拉取 redis 5.0.9 的镜像
docker pull redis:5.0.9
  • 使用 docker images 命令查看是否成功拉取镜像

注意点一:

  • docker 中的 镜像 和 容器
  • 类似于 可执行程序 和 进程 的关系

注意点二:

  • 镜像可以自己构建,也可以直接拿别人已经构建好的
  • docker hub 中包含了很多其他大佬们构建好的镜像,其中便有 Redis 官方提供的镜像

注意点三:

  • 拉取到的镜像里面包含一个精简的 Linux 操作系统,并且上面会安装 Redis
  • 只要直接基于这个镜像创建一个 容器 跑起来,此时 Redis 服务器便搭建好了!

4、基于 docker 来搭建 redis 哨兵环境

注意点一:

  • 此处涉及到多个 Redis 服务器 ,同时也有多个 Redis 哨兵节点
  • 每个 Redis 服务区 或 每个 Redis 哨兵节点 都作为一个单独的容器(6个容器)
  • 通过配置文件,把具体要创建哪些容器 和 每个容器运行的各种参数 给描述清楚
  • 后续通过一个简单的命令,便能批量的启动 或 停止这些容器了!

注意点二:

  • 此处我们使用 yml 格式来作为配置文件

注意点三:

  • 此处我们创建两个 yml 配置文件
  1. 创建三个容器,作为 Redis 的数据节点(一主两从)
  2. 创建三个容器,作为 Redis 的哨兵节点

问题:

  • 是否可以直接仅用一个 yml 配置文件直接启动上述的 6个容器?
  • 即将 Redis 的数据节点和 Redis 的哨兵节点放到一个配置文件中,然后统一启动或停止

回答:

  • 如果将这 6个容器同时启动,可能是 哨兵节点 先启动完成,数据节点后启动完成
  • 此时哨兵节点便可能会认为数据节点挂了
  • 虽然对于大局不影响,即可以成功启动,但是会影响这些节点的执行过程,从而影响后续日志的观察

注意点四:

  • 为了方便部署,此处我们使用 docker-compose 来进行 容器的编排!

5、配置数据节点的 yml 文件

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

7、启动数据节点

  • 当然我们也可以通过输入 docker-compose logs 命令来查看运行日志信息


8、配置哨兵节点的 yml 文件

 redis 哨兵节点 是单独的 redis 服务器进程

  • 根据上图所示,需要我们在 redis-sentinel 目录下创建三个 conf 文件 !!
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

 9、创建哨兵节点的三个 conf 配置文件

  • 向三个配置文件中写入相同内容
bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000

注意:

  • 初始情况下,这三个配置文件内容可以是一样的!


10、启动哨兵节点

  • 使用 docker-compose logs 查看日志文件

  • 此处我们可以看到全是报错信息
  • 该哨兵节点,不认识 redis-master
  • redis-master 相当于一个域名,docker 会自动对其进行域名解析

原因:

  • 当使用 docker-compose 启动 N个容器时
  • 此时这 N 个容器均处于同一个局域网中,因此这 N 个容器之间可以相互访问
  • 显然因为 数据节点 和 哨兵节点 并不是同时启动的!
  • 所以 三个数据节点处在一个局域网,三个哨兵节点处在另一个局域网
  • 默认情况下,这俩个局域网之间是不互通的!

实例理解

  • 使用 docker network ls 命令列出当前 docker 中的局域网

  • 此处先启动了 三个数据节点,就相当于自动创建了 第一个局域网
  • 再启动三个哨兵节点,相当于又自动创建了 第二个局域网

解决方案:

  • 可以使用 docker-compose 将此处的两组服务器给放到同一个局域网中
  • 即直接 三个哨兵节点 加入到 三个数据节点的局域网中
  • 而不是让这三个哨兵节点在启动时自动创建第二个局域网

11、在 redis-sentinel 文件下的 docker-compose.yml 配置文件下补充内容

networks:default:external:name: redisdata_default

12、重新哨兵节点的容器

  •  打开 sentinel1.conf 、sentinel2.conf、sentinel3.conf 进行观察


  • 通过上述的操作,就完成了 Docker 模拟部署哨兵模式!

关于端口映射 

  • docker 容器可以理解成是一个轻量的虚拟机
  • 在该容器中,端口号 和 外面宿主机 的端口号为两个体系

实例理解

  • 如果外面宿主机使用了 5000 端口,在容器内部也可以使用 5000 端口
  • 彼此不会冲突

  • 有时候希望在容器外面能够访问到容器内部的端口
  • 此时便需要进行端口映射,将容器里的端口映射到宿主机上
  • 后续访问宿主机的这个端口,就相当于在访问对应容器的对应端口了

  • 三个容器,每个容器内部的端口号都自成一个小天地
  • 即容器1 的 6379 和 容器2 的 6379 之间彼此不会有冲突
  • 可以把两个容器视为两个主机
  • 站在宿主的角度,访问上述几个端口时,也不知道这个端口实际上是一个宿主机上的服务,还是来自于容器内部的服务
  • 只要正常去使用即可

注意:

  • 此处的映射过程非常像 NAT

展现哨兵机制

  • 哨兵存在的意义,就是能够在 Redis 主从结构出现问题时(比如主节点挂了)
  • 此时哨兵节点便能够自动的帮我们重新选出一个节点来代替之前挂了的主节点,以此保证整个 Redis 仍然为可用状态

1、这里我们可以通过 docker stop redis-master  命令手动将主节点给干掉

  • 当主节点挂掉之后,哨兵节点便开始工作了!

2、此处我们可以观察哨兵节点的工作日志


3、此处我们连接到被选中的从节点,即新的主节点


4、此时我们重启 原 6379 端口主节点继续观察

哨兵重新选取主节点的流程

1、主观下线

  • 哨兵节点通过心跳包,判定 Redis 服务器是否正常工作
  • 如果心跳包没有如约而至,就说明该 Redis 服务器挂了
  • 当然此时并不能排网络波动的影响,因此就只能是单方面认为这个 Redis 服务器挂了

2、客观下线

  • 多个哨兵都认为主节点挂了,即 认为挂了的哨兵节点数目达到法定票数
  • 此时哨兵们便会认为该 主节点为 客观下线

问题:

  • 是否可能出现非常严重的网络波动,导致所有哨兵都联系不上 Reids 主节点,从而误判成 Redis 主节点挂了呢?

回答:

  • 可能存在!
  • 如果出现该情况,可能用户的客户端也连不上 Redis 主节点了
  • 此时这个主节点基本也无法正常工作了

注意:

  • 挂了 不一定是进程崩了
  • 只要无法正常访问,都可以视为是挂了

3、多个哨兵节点选出一个 leader 节点,由 leader 负责选出一个 从节点 作为新的主节点

  • 每个哨兵手里只有一票
  • 当哨兵1 第一个发现当前为客观下线后,便立即给自己投一票,并且告诉哨兵2 和哨兵3 我来负责这件事
  • 哨兵2 和 哨兵3 反应慢了半拍后发现为客观下线,一看哨兵1 乐意负责这件事,便立即投了赞成票

注意点一:

  • 对于哨兵2 和哨兵3 而言,当它们还未投票时,只要收到拉票请求,便会直接投出该票
  • 即 如果有多个拉票请求,会投给最先到达的

注意点二:

  • 如果总的投票数超过哨兵总数的一半,此时选举便完成了
  • 也正是因为这一点,才建议将哨兵个数设置为奇数个节点,方便投票!

注意点三:

  • 上述投票过程,就是看谁的反应快、谁的网络延时小
  • 谁的反应快,谁就最有可能成为 leader !

4、leader 选举完毕,leader 挑选一个从节点,作为新的主节点

挑选顺序如下:

  1. 优先级: 每个 Redis 数据节点都会在配置文件中,均存在优先级设置(slave-priority),即优先级最高的将成为新的主节点
  2. offset:代表从节点这边同步数据的进度,谁的数值越大,谁的数据和主节点数据就越接近,即 offset 最大的将成为新的主节点
  3. run id:每个 Redis 节点启动时,都会随机生成的一串数字(大小全凭缘分),此时将随机挑选一个成为新的主节点

5、leader 控制选中的节点执行 slave no one 命令成为 master,再控制其他节点,执行 slave of ,让其他节点以新的 master 作为主节点


小总结:

  • 以上是个常见的面试题
  • 尤其是注意选举的过程,不是直接选出新的主节点,而是先选 leader 由 leader 负责后续的主节点指定

哨兵模式注意事项

  1. 哨兵节点不能只有一个,否则哨兵节点挂了也会影响系统可用性
  2. 哨兵节点最好是奇数个,方便选举 leader ,得票更容易超过半数(大部分情况下 3 个足已)
  3. 哨兵节点不负责存储数据,仍然是 Redis 主从节点负责存储(哨兵节点就可以使用一些配置不高的机器来部署,但是不能搞一个机器部署三个哨兵)
  4. 哨兵 + 主从复制解决的问题是 提高可用性,不能解决 数据极端情况下写丢失 的问题
  5. 哨兵 + 主从复制不能提高数据的存储容量,当我们需要存的数据接近或者超过机器的物理内存,这样的结构就难以胜任了

  • Redis 集群就是解决存储容量问题的有效方案

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

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

相关文章

统一异常处理

统一异常处理 统一异常处理创建一个类定义方法ControllerAdvice和ExceptionHandler注意事项 统一异常处理 创建一个类 首先,我们来创建一个类,名字随意,这里我们取名ERHandler 定义方法 在ERHandler中,我们可以定义几个类,参数用来接收各种异常,这里的异常可以是任意的,返回…

面试官:你可以说一说你对Jmeter元素的理解吗?下

面试官:你可以说一说你对Jmeter元素的理解吗?下 监听器配置元素CSV数据集配置HTTPCookie管理器HTTP请求默认值登录配置元素 监听器 Listeners:显示测试执行的结果。它们可以以不同的格式显示结果,例如树、表、图形或日志文件 图…

LLM大语言模型(五):用streamlit开发LLM应用

目录 背景准备工作切记streamlit开发LLM demo开一个新页面初始化session先渲染历史消息接收用户输入模拟调用LLM 参考 背景 Streamlit是一个开源Python库,可以轻松创建和共享用于机器学习和数据科学的漂亮的自定义web应用程序,用户可以在几分钟内构建一…

DNS欺骗

DNS(域名系统)作为当前全球最大 、最复杂的分布式层次数据库系统,具有着开放、庞大、复杂的特性。它为全球用户提供域名解析服务,是互联网的重要基础设施。但由于其在设计之初未考虑安全性、人为破坏等因素 ,DNS系统在互联网高度发达的今天面…

Ubuntu下APT下载工具(Ubuntu 下最常用的下载和安装软件方法)

前言 本篇文章记录我学习Ubuntu 下用的最多的下载工具: APT 下载工具, APT 下载工具可以实现软件自动下载、配置、安装二进制或者源码的功能。 APT 下载工具和我们前面一篇文章讲解的“install”命令结合在一起构成了 Ubuntu 下最常用的下载和安装软件方…

【代码随想录】LC 242. 有效的字母异位词

文章目录 前言一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 前言 本专栏文章为《代码随想录》书籍的刷题题解以及读书笔记,如有侵权,立即删除。 一、题目 1、原题链接 242. 有效的字母异位词 2、题目描述 二、解题…

刘知远团队大模型技术与交叉应用L5-BMSystem

为什么需要BMTrain? PLM越来越大。为了使训练更高效和廉价。我们有必要 1.分析GPU的显存去哪了? 2.理解GPU间的合作模式是如何的? 显存都去了哪里? CPU vs GPU CPU适合复杂逻辑运算。GPU适合大量重复的数值运算。 显存成分 1.前…

csp----寻宝!大冒险!

题目描述&#xff1a; AC代码如下&#xff1a; /*思路&#xff1a; 把A变成小块 因为B是A里的一部分 通过把A变成小块 去寻找B这样速度更快 如果AB,BA&#xff0c;说明找到了。 */#include <iostream> #include <cstring> #include <algorithm> #include …

【Java】初识Spring Mvc

SpringMVC_day01 今日内容 理解SpringMVC相关概念完成SpringMVC的入门案例学会使用PostMan工具发送请求和数据掌握SpringMVC如何接收请求、数据和响应结果掌握RESTful风格及其使用完成基于RESTful的案例编写 1&#xff0c;SpringMVC简介 看到SpringMVC这个名字我们会发现其中…

【人工智能】主要人工智能技术及深度学习及传统机器学习区别与联系

主要人工智能技术的基本概念和应用场景 机器学习英文简称ML是一门涉及统计学、系统辨识、逼近理论、优化理论、计算机科学、脑科学等诸多领域的交叉学科&#xff0c;主要研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识或技能&#xff0c;重新组织已有的知识…

【GAMES101】Lecture 10 几何表示

目录 隐式表示 代数曲面&#xff08;Algebraic surfaces&#xff09; CSG&#xff08;Constructive solid geometry&#xff09; 距离函数&#xff08;Distance Functions&#xff09; 水平集&#xff08;Level set methods&#xff09; 分形&#xff08;Fractals&#x…

【Android】MediaCodec学习

在开源Android屏幕投屏代码scrcpy中&#xff0c;使用了MediaCodec去获取和display关联的surface的内容&#xff0c;再通过写fd的方式&#xff08;socket等&#xff09;传给PC端&#xff0c; MediaCodec的处理看起来比较清楚&#xff0c;数据in和数据out 这里我们做另外一个尝试…

AI嵌入式K210项目(19)-安装CanMV IDE开发软件

文章目录 前言一、软件下载安装二、软件简介三、设备连接四、在线模拟五、开机运行程序附录&#xff1a;MicroPython固件烧录总结 前言 前几章我们介绍K210使用C语言裸机开发方法&#xff0c;大家对K210内部的硬件和各种加速器有了初步的了解&#xff0c;但是开发人工智能相关…

TypeScript(四) 运算符

1. 运算符 1.1. 描述 运算符用于执行程序代码运算。 1.2. 运算符主要包括&#xff1a; &#xff08;1&#xff09;算术运算符 &#xff08;2&#xff09;逻辑运算符 &#xff08;3&#xff09;关系运算符 &#xff08;4&#xff09;按位运算符 &#xff08;5&#xff09;赋值…

内部类 --java学习笔记

内部类 是类中的五大成分之一&#xff08;成员变量、方法、构造器、内部类、代码块&#xff09;&#xff0c;如果一个类定义在另一个类的内部&#xff0c;那么这个类就是内部类当一个类的内部包含了一个整体的事务&#xff0c;且这个事务没必要单独设计时&#xff0c;就可以把…

(十三)centos7案例实战——用户、用户组及用户权限管理

前言 对于完备的centos系统来说&#xff0c;创建一套规范的账户权限系统是十分必要的。针对不同的用户提供不同的操作权限&#xff0c;避免直接使用root账号&#xff0c;造成系统的误操作&#xff0c;导致一些不必要的损失&#xff0c;将删库跑路扼杀在摇篮中。本节内容会从用…

基于springboot校园台球厅人员与设备管理系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括校园台球厅人员与设备管理系统的网络应用&#xff0c;在外国管理系统已经是很普遍的方式&#xff0c;不过国内的管理网站可能还处于起步阶段。校园台球厅人员与设备管理系统具…

Fastbee物联网项目新手快速入门

一&#xff0c;前提条件 后端环境准备如下&#xff1a; 正式环境推荐硬件资源最低要求4c8G&#xff0c;硬盘40G。JDK 1.8.0_2xx (需要小版本号大于200) 。Maven3.6.3。&#xff08;IDEA启动时使用IDEA默认自带的版本即可&#xff09;。 启动fastbee之前&#xff0c;请先确定…

课时6:编程语言逻辑

1.2.2 编程语言逻辑 学习目标 这一节&#xff0c;我们从 语言分类、编程逻辑、小结 三个方面来学习。 语言分类 语言分类 低级编程语言&#xff1a;机器&#xff1a;- 二进制的0和1的序列&#xff0c;称为机器指令。- 一般人看不懂汇编&#xff1a;- 用一些助记符号替代机…

LPC804开发(4.ctimer使用)

1.前言 昨天晚上画完板子&#xff0c;还剩点时间就再翻了翻手册&#xff0c;大致清楚了时钟树的运行&#xff0c;顺带搞清楚了定时的使用&#xff0c;那就出一份教程吧。 如果各位在此之前没有接触过LPC单片机&#xff0c;还是建议先把程序直接贴进自己的项目&#xff0c;稍微…