18.Redis之哨兵

1.哨兵机制的介绍

通过自动化的手段,来解决主节点挂了的问题~~

哨兵机制, 是通过独立的 进程 来体现的.和之前 redis-server 是不同的进程!!

redis-sentine| 不负责存储数据,只是对其他的 redis-server 进程起到监控的效果~~

通常哨兵节点,也会搞一个集合~~(多个哨兵节点构成的)

单个哨兵节点,挂了,咋办~~

Redis 的主从复制模式下,⼀旦主节点由于故障不能提供服务,需要⼈⼯进⾏主从切换,同时⼤量
的客⼾端需要被通知切换到新的主节点上,对于上了⼀定规模的应⽤来说,这种⽅案是⽆法接受的, 于是 Redis提供了 Redis Sentinel(哨兵)加个来解决这个问题。

1.1 基本概念

名词逻辑结构物理结构
主节点Redis 主服务⼀个独⽴的 redis-server 进程
从节点Redis 从服务⼀个独⽴的 redis-server 进程
Redis 数据节点主从节点主节点和从节点的进程
哨兵节点监控 Redis 数据节点的节点⼀个独⽴的 redis-sentinel 进程
哨兵节点集合若⼲哨兵节点的抽象组合若⼲ redis-sentinel 进程
Redis 哨兵(Sentinel)Redis 提供的⾼可⽤⽅案哨兵节点集合 和 Redis 主从节点
应⽤⽅泛指⼀个多多个客⼾端⼀个或多个连接 Redis 的进程

2.手动恢复redis主从复制的流程

  • 实际开发中,对于服务器后端开发,监控程序, 是非常重要的!!
  • 服务器,要求要有比较高的可用性,7*24 运行~~
  • 服务器长期运行,总会有一些"意外",具体啥时候出现了意外,咱们也不知道~~同时,也不能全靠人工来盯着服务器运行~~
  • 写一个程序,用程序来盯着服务器的运行状态~~
  • 监控程序~~
    往往还需要搭配 |报警程序"短信/电话/邮件/微信/钉钉/飞书.(给程序猿报警,通知程序猿说,这个服务器程序挂了/出问题了~-)
  • 互联网公司的程序猿,尤其是大厂,公司都会明确要求, 程序猿的手机要 24 小时开机, 并且要随时关注~~报警不仅仅是只发给这一个程序猿的~~还会发给程序猿的领导/领导的领导~~
    关键时刻,错过领导的电话, 掉链子,领导就会有比较负面的评价~~可能升职加薪就得往后稍
    稍了~~

程序猿如何恢复?

  • 1.先看看主节点还能不能抢救了,好不好抢救~~
  • 如果主节点这边是啥原因挂的,不好定位; 或者原因知道,但是短时间难以解决~
  • 2.就需要挑一个从节点,设置为新的主节点~
  • a)把选中的从节点,通过 slaveof no one,自立山头,
  • b)把其他的从节点,修改 slaveof 的主节点 ip port,连上新的主节点~
  • c)告知客户端(修改客户端的配置),让客户端能够连接新的主节点,用来完成修改数据的操作~
  • 当之前的挂了的主节点,修好了之后,就可以作为一个新的从节点,挂到这组机器中~~

只要是涉及到人工干预,不说繁琐,至少很烦人~~
另外,这个操作过程如果出错了咋办?? 可能会导致问题更加严重~~
通过人工干预的做法, 就算程序猿第一时间看到了报警信息,第一时间处理~~
恢复的过程,也需要 半个小时,以上~~
这半个小时里,整个 redis 就一直不能写????显然是不合适 

引入了哨兵机制

3.自动redis主从复制的流程

  • redis 哨兵核心功能:
  • 1.监控
  • 2.自动的故障转移
  • 3. 通知
  • 注意,redis 哨兵节点,有一个,也是可以的~~
  • 1.如果哨兵节点只有一个,它自身也是容易出现问题的~~
  • 万一这个哨兵节点挂了,后续redis节点也挂了,就无法进行自动的恢复过程了~~出现误判的概率也比较高~~
  • 2.毕竟网络传数据是容易出现抖动或者延迟或者丢包的~~ 如果只有一个哨兵节点,出现上述问题之后,影响就比较大~~

基本的原则: 在分布式系统中,应该避免使用"单点”(冗余) 

哨兵节点,最好要搞 奇数 个.最少也应该是3 个~~(方便进行选举)

4.使用docker搭建环境 

  • 按理说,这 6个节点,是要在 6个不同的服务器主机上的~~
  • 此时, 只有一个云服务器, 就在一个云服务器上,来完成这里的环境搭建~~
  • 在实际工作中,把上述节点放到一个服务器上,是没有意义的!!当前这么做只是迫于无奈~~
  • 由于这些节点,还挺多的, 相互之间容易打架;
  • 依赖的端口号/配置文件/数据文件....如果咱们直接部署,就需要小心翼翼的去避开这些冲突~~
  • 类似于咱们最开始哪种进行主从结构配置的方式~~
  • 比较繁琐; 也会和在不同主机上部署,存在较大差异~~

使用 docker 就可以有效的解决上述的问题~~ 

  • 虚拟机~~,通过软件,在一个电脑上模拟出另外的一些硬件(构造了另一个虚拟的电脑)
  • 虚拟机这样的软件,就可以使用一个计算机,来模拟出多个电脑的情况~~
  • 但是虚拟机有一个很大的问题: 比较吃配置~这个事情对于咱们的云服务器来说,压力山大~~
  • docker(现在后端开发这块非常流行的组件~~) 可以认为是一个"轻量级"的虚拟机~~ 起到了虚拟机这样的隔离环境的效果,但是又没有吃很多的硬件资源即使是配置比较拉胯的云服务器,也能构造出好几个这样的虚拟的环境~~

4.1 安装部署 (基于 docker)  

1.安装 docker 和 docker-compose

docker

yum install docker

docker-compose 的安装
# ubuntu
apt install docker-compose
# centos
yum install docker-compose

2.停⽌之前的 redis-server

# 停⽌ redis-server
service redis-server stop
# 停⽌ redis-sentinel 如果已经有的话 .
service redis-sentinel stop

 

3.使⽤ docker 获取 redis 镜像  

  • git pull 使用 git 从中央仓库拉取代码.
  • docker pull 使用 docker 从中央仓库(默认就是从 docker hub)来拉取镜像
  • 拉取到的镜像,里面包含一个精简的 Linux 操作系统, 并且上面会安装 redis ~^只要直接基于这个镜像创建一个容器跑起来,此时,redis 服务器就搭建好了~~ 

【出现问题】 

[root@iZuf6ep3mumzp5gofcygtuZ ~]# docker images
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

service docker start 

Docker启动提示:Cannot connect to the Docker daemon..._cannot connect to the docker daemon at-CSDN博客

4.启动服务器

sudo systemctl start redis

4.2 基于docker搭建redis哨兵环境 

  • 基于 docker 来搭建 redis 哨兵环境了~~
  • docker-compose 来进行 容器编排~
  • 此处涉及到多个 redis server 也有多个 redis 哨兵节点~每一个 redis server 或者每一个 redis 哨兵节点都是作为一个单独的容器了
  • 通过一个配置文件,把具体要创建哪些容器,每个容器运行的各种参数,描述清楚
  • 后续通过一个简单的命令,就能够批量的启动/停止这些容器了
  • 使用 yml 这样的格式来作为配置文件,
  • spring 也是使用 yml来作为配置文件的呀~~

1.具体步骤 

  • 1)创建三个容器, 作为 redis 的数据节点(一个主 两个从) yml
  • 2)创建三个容器,作为 redis 的哨兵节点 yml
  • 其实也是可以用一个 ym| 文件, 直接启动 6 个容器~~
  • 如果把这个6个容器同时启动,可能是 哨兵 先启动完,成,数据节点 后启动完成,哨兵可能就会先认为是数据节点挂了,虽然对于大局不影响,但是会影响到观察执行日志的过程~~
  • 所以直接分成两组,先手动启动第一组,再手动启动第二组
  • 1.1 编排 redis 主从节点

  • 1)编写yml

version: '3.3'
services:
  master:
    image: 'redis:5.0.9'
    container_name: redis-master
    restart: always
    command: redis-server --appendonly yes
    ports:
      - 6379:6379
  slave1:
    image: 'redis:5.0.9'
    container_name: redis-slave1
    restart: always
    command: redis-server --appendonly yes --slaveof redis-master 6379
    ports:
      - 6380:6379
  slave2:
    image: 'redis:5.0.9'
    container_name: redis-slave2
    restart: always
    command: redis-server --appendonly yes --slaveof redis-master 6379
    ports:
      - 6381:6379

2) 启动所有容器
docker-compose up -d

3) 查看运⾏⽇志
docker-compose logs
 4) 验证
1.连接主节点
redis-cli -p 6379
info replication

 成功!!!

2.连接从节点
redis-cli -p 6380

redis-cli -p 6381  

 1.2 编排 redis-sentinel 节点

1) 编写 docker-compose.yml
创建 /root/redis-sentinel/docker-compose.yml , 同时 cd 到 yml 所在⽬录中.
注意: 每个⽬录中只能存在⼀个 docker-compose.yml ⽂件.
version: '3.3'
services:
  sentinel1:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-1
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel1.conf:/etc/redis/sentinel.conf
    ports:
      - 26379:26379
  sentinel2:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-2
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel2.conf:/etc/redis/sentinel.conf
    ports:
      - 26380:26379
  sentinel3:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-3
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel3.conf:/etc/redis/sentinel.conf
    ports:
      - 26381:26379
networks:
  default:
    external:
      name: redisdata_default

其中最后一行的name要与以下配置相对应

2) 创建配置⽂件
创建 sentinel1.conf sentinel2.conf sentinel3.conf . 三份⽂件的内容是完全相同
的.
都放到 /root/redis-sentinel/ ⽬录中.
bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000
理解 sentinel monitor

sentinel monitor 主节点名 主节点ip 主节点端⼝ 法定票数 

主节点名, 这个是哨兵内部⾃⼰起的名字.
主节点 ip, 部署 redis-master 的设备 ip. 此处由于是使⽤ docker, 可以直接写 docker 的容器名, 会
被⾃动 DNS 成对应的容器 ip
主节点端⼝, 不解释.
法定票数, 哨兵需要判定主节点是否挂了. 但是有的时候可能因为特殊情况, ⽐如主节点仍然⼯作正常, 但是哨兵节点⾃⼰⽹络出问题了, ⽆法访问到主节点了. 此时就可能会使该哨兵节点认为主节点下线, 出现误判. 使⽤投票的⽅式来确定主节点是否真的挂了是更稳妥的做法. 需要多个哨兵都认为主节点挂了, 票数 >= 法定票数 之后, 才会真的认为主节点是挂了.
理解 sentinel down-after-milliseconds
主节点和哨兵之间通过⼼跳包来进⾏沟通. 如果⼼跳包在指定的时间内还没回来, 就视为是节点出现故障

既然内容相同, 为啥要创建多份配置⽂件?

redis-sentinel 在运⾏中可能会对配置进⾏ rewrite, 修改⽂件内容. 如果⽤⼀份⽂件, 就可能出现修改
混乱的情况.
3) 启动所有容器

docker-compose up -d

如果启动后发现前⾯的配置有误, 需要重新操作, 使⽤ docker-compose down 即可停⽌并删除刚才创建好的容器.
4) 查看运⾏⽇志
docker-compose logs
上述操作必须保证⼯作⽬录在 yml 的同级⽬录中, 才能⼯作.
可以看到, 哨兵节点已经通过主节点, 认识到了对应的从节点.

 

 哨兵启动后自动修改

5.哨兵节点的作用

  • 哨兵存在的意义,能够在 redis 主从结构出现问题的时候(比如主节点挂了),此时哨兵节点就能够自动的帮我们重新选出一个主节点,来代替之前挂了的节点、保证整个 redis 仍然是可用状态.
  • 手动把主节点给干掉.
  • 当主节点挂了之后,哨兵节点就开始工作了!!
  • sdown 主观下线: 本哨兵节点,认为该主节点挂了
  • odown 客观下线: 好几个哨兵都认为该节点挂了,达成了一致(法定票数)
  • 此时,主节点挂了这个事情就被石锤了~~
  • 此时就需要哨兵节点选出一个从节点,作为新的主节点,此处就需要提拔出一个新的主节点~~

6.主从切换的具体流程 

1.主观下线.

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

2.客观下线.

多个哨兵都认为主节点挂了。(认为挂了的哨兵节点数目达到 法定票数)哨兵们就认为这个主节点是 客观下线

【比如是否可能出现非常严重的网络波动导致所有的哨兵都联系不上 redis 主节点误判成挂了呢??

当然是有的!!!

如果出现这个情况,怕是用户的客户端也连不上 redis 主节点了..此时这个主节点基本也就无法正常工作了

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

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

上面投票过程,看谁反应快(谁网络延时小)

4.此时 leader 选举完毕,leader 就需要挑选一个从节点,作为新的主节点.
  • 1)优先级
  • 每个 redis 数据节点,都会在配置文件中,有一个优先级的设置.slave-priority优先级高的从节点,就会胜出~~~
  • 2) offset最大,就胜出.
  • offset 从节点从主节点这边同步数据的进度.数值越大,说明从节点的数据和主节点就越接近.
  • 3)run id 每个 redis 节点启动的时候随机生成的一串数字~~(大小全凭缘分了)
  • 把新的主节点指定好了之后,
    leader 就会控制这个这个节点,执行 slave no one,成为 master,
    再控制其他节点,执行 slave of,让这些其他节点,以新的 master 作为主节点了

经典面试顾~~
尤其是注意选举的过程
不是直接选出新的主节点,而是先选 leader
由 leader 负责后续的主节点指定~~

7.小结 

上述过程, 都是 "⽆⼈值守" , Redis ⾃动完成的. 这样做就解决了主节点宕机之后需要⼈⼯⼲预的问题, 提⾼了系统的稳定性和可⽤性.
⼀些注意事项:
哨兵节点不能只有⼀个. 否则哨兵节点挂了也会影响系统可⽤性.
哨兵节点最好是奇数个. ⽅便选举 leader, 得票更容易超过半数.(大部分3个足以)
哨兵节点不负责存储数据. 仍然是 redis 主从节点负责存储.(哨兵节点就可以使用一些配置不
高的机器来部署.(但是不能搞一个机器部署三个哨兵))
哨兵 + 主从复制解决的问题是 "提⾼可⽤性", 不能解决 "数据极端情况下写丢失" 的问题.
哨兵 + 主从复制不能提⾼数据的存储容量. 当我们需要存的数据接近或者超过机器的物理内存, 这样的结构就难以胜任了.
为了能存储更多的数据, 就引⼊了集群.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

汽车MCU虚拟化--对中断虚拟化的思考(2)

目录 1.引入 2.TC4xx如何实现中断虚拟化 3.小结 1.引入 其实不管内核怎么变,针对中断虚拟化无非就是上面两种,要么透传给VM,要么由Hypervisor统一分发。汽车MCU虚拟化--对中断虚拟化的思考(1)-CSDN博客 那么,作为车规MCU龙头…

基于ES安装IK分词插件

前言 IK分词器插件是为Elasticsearch设计的中文分词插件,由Elasticsearch的官方团队之外的开发者medcl开发。它主要针对中文文本的分词需求,提供了较为准确的中文分词能力。以下是IK分词器插件的一些特点: 智能分词:IK分词器采用基…

thinkphp6 自定义的查询构造器类

前景需求&#xff1a;在查询的 时候我们经常会有一些通用的&#xff0c;查询条件&#xff0c;但是又不想每次都填写一遍条件&#xff0c;这个时候就需要重写查询类&#xff08;Query&#xff09; 我目前使用的thinkphp版本是6.1 首先自定义CustomQuery类继承于Query <?p…

戴尔科技:一盆冷水浇醒了AIPC

这年头&#xff0c;只要沾上英伟达的公司&#xff0c;不论美股还是大A,都跟着鸡犬升天几轮过&#xff0c;但昨晚英伟达蒸发1064亿美元&#xff0c; 跟着遭罪的也不少&#xff0c;有没有一夜惊魂梦醒的感觉&#xff1f; 今天我们来说说——戴尔科技。 昨晚戴尔科技大跌5.18%&a…

R语言ggplot2包绘制网络地图

重要提示&#xff1a;数据和代码获取&#xff1a;请查看主页个人信息&#xff01;&#xff01;&#xff01; 载入R包 rm(listls()) pacman::p_load(tidyverse,assertthat,igraph,purrr,ggraph,ggmap) 网络节点和边数据 nodes <- read.csv(nodes.csv, row.names 1) edges…

网页截图并添加美观外壳:无需PS轻松实现的方法

在日常生活和工作中&#xff0c;我们经常需要截取网页的屏幕快照&#xff0c;以便于分享、保存或用于其他用途。尽管许多人认为使用Photoshop&#xff08;PS&#xff09;是最佳选择&#xff0c;但实际上&#xff0c;有许多更简单、快捷的方法可以帮助我们实现这一目标&#xff…

时间控件,开始时间和结束时间限制

****开始时间必须小于结束时间 如果选择了结束时间&#xff0c;开始时间必须小于结束时间 //开始时间<el-date-pickerstyle"width:190px;"v-model"searchForm.clsjdate"placeholder"请选择日期"type"date"value-format"yyyy-…

【学习笔记】数据结构(二)

线性表 文章目录 线性表1、线性结构2、线性表2.1 线性表定义2.2 类型定义2.2 顺序存储结构&#xff08;Sequence List&#xff09;2.3 链式存储结构2.3.1 单链表2.3.2 循环链表2.3.3 双链表2.3.4 单链表、循环链表、双向链表的时间效率比较2.3.5 链式存储结构优缺点 2.4 顺序表…

可用于嵌入式的解释器调研对比,及lua解释器介绍

嵌入式不一定只能用C! ---------------------------------------------------------------------------------------手动分割线-------------------------------------------------------------------------------- 本文章参考了以下文章&#xff1a; 这里是引用 ------------…

城市之旅:使用 LLM 和 Elasticsearch 简化地理空间搜索(二)

我们在之前的文章 “城市之旅&#xff1a;使用 LLM 和 Elasticsearch 简化地理空间搜索&#xff08;一&#xff09;”&#xff0c;在今天的练习中&#xff0c;我将使用本地部署来做那里面的 Jupyter notebook。 安装 Elasticsearch 及 Kibana 如果你还没有安装好自己的 Elasti…

字符串 | 字符串匹配之 KMP 算法以及 C++ 代码实现

目录 1 为什么使用 KMP&#xff1f;2 什么是 next 数组&#xff1f;2.1 什么是字符串的前后缀&#xff1f;2.2 如何计算 next 数组&#xff1f; 3 KMP 部分的算法4 完整代码 &#x1f608;前言&#xff1a;这篇文章比较长&#xff0c;但我感觉自己是讲明白了的 1 为什么…

迈的普拉姆利普绘图:深入解析与实战应用

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;matplotlib绘图的基本原理 代码案例 二、深入了解&#xff1a;matplo…

Android更新优化 - 增量更新是如何节省用户时间和流量的

增量更新和全量更新 我想玩过大型手游的人都知道&#xff0c;手游的安装包非常大&#xff0c;因为资源图片众多。而你每次更新都把所有文件都更新下来&#xff0c;是非常耗时的&#xff0c;对吧。耗时是一个方面&#xff0c;有些人在户外开的是移动网络&#xff0c;动不动就几…

vue3 侦听器

侦听器示例 计算属性允许我们声明性地计算衍生值。然而在有些情况下&#xff0c;我们需要在状态变化时执行一些“副作用”&#xff1a;例如更改 DOM&#xff0c;或是根据异步操作的结果去修改另一处的状态。 在组合式 API 中&#xff0c;我们可以使用 watch 函数在每次响应式…

模型构建器之迭代器

上一篇我们介绍了模型构建器的基础&#xff0c;将一个工作流串联起来&#xff0c;然后做成模型工具。今天我们介绍模型构建器的第二个重要功能——迭代&#xff0c;也就是程序中的循环。 先来看一个例子。要给数据库中所有要素类添加一个相同的字段&#xff0c;该怎么做&#…

Diffusion Model, Stable Diffusion, Stable Diffusion XL 详解

文章目录 Diffusion Model生成模型DDPM概述向前扩散过程前向扩散的逐步过程前向扩散的整体过程 反向去噪过程网络结构训练和推理过程训练过程推理过程优化目标 详细数学推导数学基础向前扩散过程反向去噪过程 Stable Diffusion组成结构运行流程网络结构变分自编码器 (VAE)文本编…

ctfshow-web入门-信息搜集(web1-web10)

勇师傅还是想打 CTF 目录 1、web1 2、web2 3、web3 4、web4 5、web5 6、web6 7、web7 8、web8 9、web9 10、web10 1、web1 开发注释未及时删除 F12 看源码 拿到 flag&#xff1a;ctfshow{99854d7a-54a2-491a-8626-d5bfe7b5c2ca} 2、web2 js前台拦截 无效操作 按 F12 …

分享 ASP.NET Core Web Api 中间件获取 Request Body 两个方法

不废话&#xff0c;直接上正文。_ 方法一 思路&#xff1a;利用 BodyReader 直接读取 HttpContext 的 Request Body&#xff0c;再反序列化 var reqStream context.Request.BodyReader.AsStream(); var jsonObj JsonSerializer.Deserialize<CheckAndParsingMiddlewareM…

5.25.1 用于组织病理学图像分类的深度注意力特征学习

提出了一种基于深度学习的组织病理学图像分类新方法。我们的方法建立在标准卷积神经网络 (CNN) 的基础上,并结合了两个独立的注意力模块,以实现更有效的特征学习。 具体而言,注意力模块沿不同维度推断注意力图,这有助于将 CNN 聚焦于关键图像区域,并突出显示判别性特征通…

Xilinx IP解析之DDS Compiler v6.0(1)—— 基础概念

前言 DDS&#xff08;Direct Digital Synthesis&#xff0c;直接数字综合器&#xff09;是一种正弦波发生器&#xff0c;在Quartus中它被称为NCO&#xff08;Numerically Controlled Oscillator&#xff0c;数控振荡器&#xff09;&#xff0c;两者是对同一功能IP核的不同称呼。…