redis哨兵模式原理

news2024/10/6 2:27:52

概述

  为了实现redis集群的高可用,redis经历了好几次迭代,从最开始的主从模式,到哨兵模式,再到现在的集群模式,可以说架构的优化越来越好,那本篇文章就介绍一下redis的哨兵模式,不过我司其实使用的是cluster模式,这里就当学习一下。

redis哨兵模式架构

  

   声明:本图来源Redis ==> 集群的三种模式

  要解释什么是哨兵模式,要从redis的主从模式说起,redis的主从模式就是把上图的所有的哨兵去掉,就变成了主从模式,主从模式是主节点负责写请求,然后异步的同步给从节点,然后从节点负责读请求,所以在主从架构中redis每个节点保存的数据是相同的,只是数据的同步可能会有一点延迟,那考虑到高可用性,如果主节点挂了,是没有一个自动选主的机制的,需要人工来指定一个节点为主节点,然后再恢复成主从结构,所以其实也是不能做到高可用。

  为了解决主从模式不能高可用的问题,就发明了哨兵模式,所谓的哨兵模式,就是在原来的主从架构的基础上,又搞了一个集群,哨兵集群,这个集群会监控redis集群的主节点和从节点的状态,如果发现主节点挂了,就会重新在从节点中选出来一个作为主节点,从而做到高可用。

  那哨兵本身是一个集群,那这个集群之间是怎么通信的呢?哨兵模式既然可以监控redis集群,做到故障转移,哨兵集群又是怎么监控redis集群的呢?下面就分析这两个问题

回到顶部

哨兵模式工作原理

  哨兵集群中的每个节点都会启动三个定时任务

  • 第一个定时任务: 每个sentinel节点每隔1s向所有的master、slaver、别的sentinel节点发送一个PING命令,作用:心跳检测
  • 第二个定时任务: 每个sentinel每隔2s都会向master的__sentinel__:hello这个channel中发送自己掌握的集群信息和自己的一些信息(比如host,ip,run id),这个是利用redis的pub/sub功能,每个sentinel节点都会订阅这个channel,也就是说,每个sentinel节点都可以知道别的sentinel节点掌握的集群信息,作用:信息交换,了解别的sentinel的信息和他们对于主节点的判断
  • 第三个定时任务: 每个sentinel节点每隔10s都会向master和slaver发送INFO命令,作用:发现最新的集群拓扑结构

回到顶部

哨兵如何判断master宕机

主观下线

  这个就是上面介绍的第一个定时任务做的事情,当sentinel节点向master发送一个PING命令,如果超过own-after-milliseconds(默认是30s,这个在sentinel的配置文件中可以自己配置)时间都没有收到有效回复,不好意思,我就认为你挂了,就是说为的主观下线(SDOWN),修改其flags状态为SRI_S_DOWN

客观下线

  要了解什么是客观下线要先了解几个重要参数:

  • quorum:如果要认为master客观下线,最少需要主观下线的sentinel节点个数,举例:如果5个sentinel节点,quorum = 2,那只要2个sentinel主观下线,就可以判断master客观下线
  • majority:如果确定了master客观下线了,就要把其中一个slaver切换成master,做这个事情的并不是整个sentinel集群,而是sentinel集群会选出来一个sentinel节点来做,那怎么选出来的呢,下面会讲,但是有一个原则就是需要大多数节点都同意这个sentinel来做故障转移才可以,这个大多数节点就是这个参数。注意:如果sentinel节点个数5,quorum=2,majority=3,那就是3个节点同意就可以,如果quorum=5,majority=3,这时候majority=3就不管用了,需要5个节点都同意才可以。
  • configuration epoch:这个其实就是version,类似于中国每个皇帝都要有一个年号一样,每个新的master都要生成一个自己的configuration epoch,就是一个编号

客观下线处理过程

  1. 每个主观下线的sentinel节点都会向其他sentinel节点发送 SENTINEL is-master-down-by-addr ip port current_epoch runid,(ip:主观下线的服务id,port:主观下线的服务端口,current_epoch:sentinel的纪元,runid:*表示检测服务下线状态,如果是sentinel 运行id,表示用来选举领头sentinel(下面会讲选举领头sentinel))来询问其它sentinel是否同意服务下线。
  2. 每个sentinel收到命令之后,会根据发送过来的ip和端口检查自己判断的结果,如果自己也认为下线了,就会回复,回复包含三个参数:down_state(1表示已下线,0表示未下线),leader_runid(领头sentinal id),leader_epoch(领头sentinel纪元)。由于上面发送的runid参数是*,这里后两个参数先忽略。
  3. sentinel收到回复之后,根据quorum的值,判断达到这个值,如果大于或等于,就认为这个master客观下线

选择领头sentinel的过程

  到现在为止,已经知道了master客观下线,那就需要一个sentinel来负责故障转移,那到底是哪个sentinel节点来做这件事呢?需要通过选举实现,具体的选举过程如下:

  1. 判断客观下线的sentinel节点向其他节点发送SENTINEL is-master-down-by-addr ip port current_epoch runid(注意:这时的runid是自己的run id,每个sentinel节点都有一个自己运行时id)
  2. 目标sentinel回复,由于这个选择领头sentinel的过程符合先到先得的原则,举例:sentinel1判断了客观下线,向sentinel2发送了第一步中的命令,sentinel2回复了sentinel1,说选你为领头,这时候sentinel3也向sentinel2发送第一步的命令,sentinel2会直接拒绝回复
  3. 当sentinel发现选自己的节点个数超过majority(注意上面写的一种特殊情况quorum>majority)的个数的时候,自己就是领头节点
  4. 如果没有一个sentinel达到了majority的数量,等一段时间,重新选举

回到顶部

故障转移过程

  通过上面的介绍,已经有了领头sentinel,下面就是要做故障转移了,故障转移的一个主要问题和选择领头sentinel问题差不多,到底要选择哪一个slaver节点来作为master呢?按照我们一般的常识,我们会认为哪个slaver中的数据和master中的数据相识度高哪个slaver就是master了,其实哨兵模式也差不多是这样判断的,不过还有别的判断条件,详细介绍如下:

  在进行选择之前需要先剔除掉一些不满足条件的slaver,这些slaver不会作为变成master的备选

  • 剔除列表中已经下线的从服务
  • 剔除有5s没有回复sentinel的info命令的slaver
  • 剔除与已经下线的主服务连接断开时间超过 down-after-milliseconds*10+master宕机时长的slaver

选主过程

  1. 选择优先级最高的节点,通过sentinel配置文件中的replica-priority配置项,这个参数越小,表示优先级越高
  2. 如果第一步中的优先级相同,选择offset最大的,offset表示主节点向从节点同步数据的偏移量,越大表示同步的数据越多
  3. 如果第二步offset也相同,选择run id较小的

后续事项

  新的主节点已经选择出来了,并不是到这里就完事了,后续还需要做一些事情,如下

  1. 领头sentinel向别的slaver发送slaveof命令,告诉他们新的master是谁谁谁,你们向这个master复制数据
  2. 如果之前的master重新上线时,领头sentinel同样会给起发送slaveof命令,将其变成从节点

哨兵模式存在的问题

任何一种模式都不是完美的,哨兵模式也不例外,下面就介绍一下这种模式存在的一些问题

回到顶部

主节点写压力过大

  由于只有主节点负责写数据,如果有大量的写请求的时候,主节点负载太高,有挂掉的风险

  解决办法:使用cluster模式^_^

集群脑裂

  所谓的集群脑裂,就是一个集群中出现了两个master,这种情况是如何产生的呢?当集群中的master的网络出现了问题,和集群中的slaver和sentinel通信出现问题,但是本身并没有挂,见下图

 声明:本图来源:redis 脑裂等极端情况分析

这时,由于sentinel连接不上master,就会重新选择一个新的slaver变成master,这时候如果client还么有来得及切换,就会把数据写入到原来的那个master中,一旦网络恢复,原来的master就会被变成slaver,从新的master上复制数据,那client向原来的master上写的数据就丢失了。

解决办法:在redis的配置文件中有如下两个配置项

  • min-slavers-to-write 1
  • min-slavers-max-lag 10

这两个配置项组合在一起配置的意思就是至少有一个slaver和master数据同步延迟不超过10s,如果所有的slaver都超过10s,那master就会拒绝接收请求,为什么加了这两个参数就可以解决问题呢?如果发生脑裂,如果client向旧的master写数据,旧的master不能向别的slaver同步数据,所以client最多只能写10s的数据。这里有些萌新可能就会有问题了,如果发生脑裂的时候,之前集群中的master和一个slaver都与别的slaver和sentinel无法通信了,但是这两个哥们还可以通信,那这个slaver不就可以正常从master同步数据吗,不就满足了上面的两个条件了吗,对,确实会这样^_^,所以你可以把min-slavers-to-write配置大一点

主从数据不一致

  这个没办法,异步复制确实会有这个问题,如果系统可以接受这一点延迟,那就没问题,如果一定要没有一点延迟,那就指定读主库吧。

总结

  本文介绍了什么是哨兵模式,以及哨兵模式中如何选择领头sentinel来做故障转移和故障转移的过程,之后又介绍了哨兵模式的一些问题,一般来说吧,如果redis中的数据量不是很大都可以使用这种模式,比如就几个G的数据,使用哨兵模式没什么问题。

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

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

相关文章

阿里云服务器部署flask简单方法

记录如何在阿里云服务器上部署flask接口并实现公网访问。 文章目录 1. 简介2. 部署python3环境3. 生成requirement.txt4. 将项目打包上传5. 安装依赖库6. 查看防火墙7. 测试能否公网访问 1. 简介 因落地通话callback服务测试,需要我写一个测试demo,用于…

Unity Shader中使用GLSL创建材质

目录 Unity Shader格式Properties怎么在脚本中使用类似于glUniform()的功能呢? SubShaderTagsLODpasspass内的tags说明pass内的代码段(GLSL)GLSL与CG语言的差异1. GLSL不可在外部定义结构体2. 在UnityShader中Uniform可以写在vert frag外面 S…

如何处理图片排重(精准排重,相似排重)

图片相似度对比 1、需求 假如有一个图片池,存有1亿图片。给一张目标图片,在图片池中做匹配。 判断一张图片是否在图片池中出现过。(完全一样)判断有没有相似的出现过。比如两张图相似度90,两张图片是在描述一件事情。 …

请推荐几个github上的vue的pc端项目?

前言 这是github上一些高收藏的vue PC端的项目,花了一点时间做了一下vue2和vue3的资源分类整理,可以根据自己的学习进度以及需求来选择对应的项目来研究,希望对你有帮助~ Vue2 PC项目 1、 Elemen Star:53.4k 是一个基于Vue.js…

【Unity Optimize】使用图集(Sprite Atlas)优化项目

目录 1 图集(Sprite Atlas)介绍2 创建与配置Sprite Atlas2.1 创建Sprite Atlas2.1.1 Unity2D项目2.1.2 Unity3D项目 2.2 配置Sprite Atlas2.3 注意事项 3 Sprite Atlas的接口4 Sprite Atlas的优化建议 1 图集(Sprite Atlas)介绍 …

vue3+element plus+vite 引入本地静态资源图片require报错的原因和解决方案,以及如何在表格中展示图片

文章目录 一、vue3element plusvite 引入本地静态资源图片require报错的原因和解决方案二、vue 3element plusvite 项目中,在el-table中展示本地静态图片总结 一、vue3element plusvite 引入本地静态资源图片require报错的原因和解决方案 在写vue3vite项目的过程中…

Java-代码连接数据库生成POJO、Mapper

本文主要介绍如何在IDEA中,编写代码连接数据库生成对应的POJO、Mapper、Service、Controller 文章目录 前言环境搭建代码开发基本配置常量信息代码生成 测试结果 前言 在实际开发中,设计完数据库后,不可避免需要创建数据库表对应的POJO&…

rt-thread汇总

finish和msh的区别? 这个问题我一直没搞懂,可能得看一下源码才能搞清楚了吧 通过Qemu运行RT-Thread 在windows上通过QEMU快速上手RT-thread smart RT-thread启动流程 rt-thread启动流程 Kconfig语法 Kconfig语法 LOG输出 rt_kprintf("Hello …

InsCode AI ,你的良师益友!

Chat-GTP的火爆程度相信大家已经听说了,也对它有一个基本的初识,它是Open AI所研发的,读者当中应该有不少人已经接触和体验人工智能聊天,以及使用它交流很多问题有关于生活,学习等,而 InsCode AI 也一样能够…

javaWeb ssh学堂在线管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh学堂在线管理系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0…

30天从入门到精通TensorFlow1.x 第三天,tf.variable_scope()共享或重用变量

tf.variable_scope()共享或重用变量 文章目录 一、接前一天二、tf.variable_scope()共享或重用变量1. 背景2. 目的3. tf.variable_scope()基本参数3. tf.variable_scope()作用(1).命名空间(2).共享变量(3).…

软考A计划-电子商务设计师-电子商务相关技术与应用基础知识

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&am…

cesium 相机相关

1 相机的初始位置 /*** The default rectangle the camera will view on creation.* type Rectangle*/ Camera.DEFAULT_VIEW_RECTANGLE Rectangle.fromDegrees(-95.0,-20.0,-70.0,90.0 );// set default view rectangleCameraPosition3D(this,Camera.DEFAULT_VIEW_RECTANGLE,…

Async 使用详解

Spring Boot异步调用Async 在实际开发中,有时候为了及时处理请求和进行响应,我们可能会多任务同时执行,或者先处理主任务,也就是异步调用,异步调用的实现有很多,例如多线程、定时任务、消息队列等&#xf…

若依框架快速搭建(二)

目录 数据库设计功能模块设计XXX信息管理xxx查询xxx添加xxx删除xxx修改xxx导出 功能模块实现运行数据库自动代码生成在IDEA中找到RuoYi-generator,修改配置运行前后端项目,在网页中找到代码生成模块导入表后点击确定,序号前打勾,再…

Mac - 光标特效 By CursorEffect2

目录 一.引言 二.安装 CursorEffect2 三.使用 CursorEffect2 四.使用效果 五.内存消耗 六.一键关闭 七.总结 一.引言 在自己搭建的 Hexo 博客上可以定义鼠标点击的特效,如图点击后可以产生彩色的斑点。 于是想着除了浏览 Hexo 博客外,能不能别的也…

【笔试强训编程题】Day1.(组队竞赛100449)和(删除公共字符69390)

作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:笔试强训编程题 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!! 文章目录…

【CSS3系列】第一章 · CSS3新增的三种基本属性

写在前面 Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正&#xff0…

FineBI6.0基础学习第一课 数据门户

PC端门户使用示例 首先,以管理员身份登录FineBI系统,安装数据门户,安装步骤见官网 新建一个数据门户

SouapUI接口测试之创建性能测试

SouapUI也是一个能生动的体现一个系统(项目)性能状态的工具,本篇就来说说如何在SouapUI工具下创建性能测试 一、创建测试用例 由于在《SouapUI接口测试之使用Excel进行参数化》篇已经创建好了测试用例,本篇就不讲解如何创建测试…