Redis-哨兵

news2024/10/4 4:58:03

概念 

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-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
~                           

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-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

 

哨兵节点,会在运行过程中,对配置文件进行自动的修改

因此,就不能拿一个配置文件,给三个容器分别映射

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

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-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: 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主从节点负责存储.
  • 哨兵+主从复制解决的问题是"提⾼可⽤性",不能解决"数据极端情况下写丢失"的问题.
  • 哨兵+主从复制不能提⾼数据的存储容量.当我们需要存的数据接近或者超过机器的物理内存,这样 的结构就难以胜任了.为了能存储更多的数据,就引⼊了集群

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

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

相关文章

16.数据结构与算法-串,数组与广义表(串,BF算法,KMP算法)

串(String) 串的定义 关于串的术语 串的案例引入 串的类型定义 串的顺序存储结构 串的链式存储结构-块链结构 串的模式匹配算法(BF算法与KMP算法) BF算法 BF算法时间复杂度 KMP算法

CSS滚动条

通过《CSS盒子模型》一节的学习我们知道,页面中的每个元素都可以看作是一个矩形的盒子,我们可以使用 CSS 来控制盒子的大小、位置等等信息。默认情况下,当元素中的内容超出盒子的大小时,例如元素内容区的宽度和高度所组成的矩形区…

Django连接Dify、ChatGPT4o并计算tokens数量方法

通过Dify可以连接很多模型国内、国外的都可以进行选择可以到Dify里创建一个空白应用,然后点击进入就可以看到API了api_url "http://192.168.15.131/v1/chat-messages" api_key "app-UtzTpVNwpTLUcGvRNnnK9QNY" headers {"Authorization…

网站开发基础:JavaScript

前端开发主要使用的技术如 HTML、CSS 和 JavaScript 等。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>.myDivClass{border: solid red 1px;width: 50px;height:…

python如何查询函数

1、通用的帮助函数help() 使用help()函数来查看函数的帮助信息。 如&#xff1a; import requests help(requests) 会有类似如下输出&#xff1a; 2、查询函数信息 ★查看模块下的所有函数&#xff1a; dir(module_name) #module_name是要查询的函数名 如&#xff1a; i…

【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…

PCL 点云统计滤波

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 统计滤波实现 2.1.2 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#xf…

Android SystemUI组件(10)禁用/重启锁屏流程分析

该系列文章总纲链接&#xff1a;专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节持续迭代之前章节的思维导图&#xff0c;主要关注左侧上方锁屏分析部分 应用入口处理流程解读 即可。 在 Android 系统中&#xff0c;禁用锁屏…

C++初学者指南-5.标准库(第二部分)–随机数生成

C初学者指南-5.标准库(第二部分)–随机数生成 文章目录 C初学者指南-5.标准库(第二部分)–随机数生成基本概念例子统一随机数布尔值&#xff08;“抛硬币”&#xff09;正态分布具有独立概率的整数 怎么做种子引擎使用自定义生成器 shuffle算法分布类型概述通用接口均匀分布采样…

虚拟机 VMware 安装 macOS

macOS 界面 MAC OS IOS下载&#xff1a; amacOS Monterey by Techrechard.comwmacOS Monterey by Techrechard.com 下载&#xff1a;Unlocker-v2.0.1-x64 Mac OS X 虚拟机中更改屏幕分辨率 终端输入命令&#xff1a; sudo defaults write /Library/Preferences/com.apple.w…

C++11bind、function、lambda详细讲解

一.lambda表达式 关于lambda表达式&#xff0c;我之前是详细讲过的&#xff0c;现在我们只来做重点讲解&#xff08;如果存在疑问可以回看我之前的作品&#xff09;。 固定格式&#xff1a; []()->返回值{};([capture-list] (parameters) mutable -> return-type { state…

UE行为树编辑器图文笔记

对UE的编辑器实现有点好奇&#xff0c;于是从比较熟悉的行为树编辑器着手分析。以下为阅读UE源码后的个人理解&#xff0c;如有错误请指正。 编辑器基础 扩展编辑器的几种方式 MenuBar 菜单栏ToolBar 工具栏DetailCustomization 自定义细节面板&#xff0c;支持两种方式&…

西安做网站如何打造出色的企业网站

西安做网站如何打造出色的企业网站 随着数字化时代的到来&#xff0c;企业网站已成为展示企业形象、传播品牌价值的重要平台。在西安&#xff0c;如何打造出色的企业网站呢&#xff1f;以下几点建议可以帮助企业在激烈的竞争中脱颖而出。 **1. 清晰的网站定位** 首先&#xff…

【Godot4.3】匀速和匀变速直线运动粒子

概述 本篇论述&#xff0c;如何用加速度在Godot中控制粒子运动。 匀速和匀变速直线运动的统一 以下是匀变速运动的速度和位移公式&#xff1a; v t v 0 a t x t v 0 t 1 2 a t 2 v_tv_0 at \\ x_tv_0t \frac{1}{2}at^2 vt​v0​atxt​v0​t21​at2 当a 0 时&#xf…

计算机科学英语词汇汇总(下)Computer Science English Complete Vocabulary )

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

0基础学习QT——配置开发环境

大纲 安装Qt配置Visual Studio 2022安装插件配置 测试 Qt框架&#xff0c;以其跨平台、高性能以及丰富的UI组件库而著称&#xff0c;是开发图形用户界面应用程序的理想选择。Visual Studio 2022提供了对Qt项目的深度支持&#xff0c;包括智能代码提示、代码导航、调试工具等&am…

(14)MATLAB莱斯(Rician)衰落信道仿真4

文章目录 前言一、改写莱斯分布概率密度函数的理论值二、仿真代码三、仿真结果总结 前言 本文通过将接收信号总功率设置为1&#xff0c;重写了莱斯衰落信道上接收信号幅度的理论PDF式。然后用MATLAB代码生成了在具有不同莱斯因子K的Ricean平坦衰落信道下接收到的信号样本&…

容器适配器-stack、queue、priority_queue和仿函数

目录 1.什么是适配器 2.deque 1.简单了解结构 2.deque的缺陷 3.为什么选择deque作为stack和queue的底层默认容器 3.stack&#xff08;栈&#xff09; 4.queue&#xff08;队列&#xff09; 5.仿函数 6.priority_queue&#xff08;优先级队列&#xff09;&#xff08;堆…

PlantUML中的实体关系图

概述 实体关系图&#xff08;Entity Relationship Diagrams&#xff0c;ERD&#xff09;是一种被广泛用于数据库建模的图。 1976年美籍华裔计算机科学家陈品山&#xff08;Peter Chen&#xff09;首次提出了Entity Relationship Modeling&#xff08;实体关系建模&#xff09…

数据结构-单链表的反转

一直在路上 目录 前言一、普通方法二、头插法三、递归法总结 前言 本篇文章介绍反转单链表的三种方法&#xff0c;分别为普通方法、头插法、递归法。 一、普通方法 普通方法是从第一个结点开始反转&#xff0c;然后反转剩余的结点。 普通方法需要保存当前结点的前驱和后继&a…