详解redis哨兵(高可用)

news/2024/12/23 18:18:35 标签: redis, 数据库, 运维, linux

华子目录

  • `为什么会出现redis的哨兵?`
  • `redis哨兵`
  • 哨兵机制能做什么?
  • 什么是主观下线和客观下线?
    • 主观下线
    • 客观下线
  • 哨兵的三个定时监控
  • master主节点下线后,怎么进行故障转移?
    • leader哨兵的选举
    • 故障转移,选举`新的master`
      • 执行故障转移
  • `客户端`是和`哨兵通信`还是`redis集群通信`?
  • 实验步骤
    • `编辑sentinel.conf`
    • 做`sentinel.conf.bak备份`
    • 开启哨兵
    • 测试
  • 在`整个哨兵`和`主从架构`中可能会出现的`问题`

redis_1">为什么会出现redis的哨兵?

  • redis主从复制架构中,一旦当master挂掉后,就没有slave接替他,这时就需要用到哨兵redis的高可用

redis_4">redis哨兵

在这里插入图片描述
在这里插入图片描述

  • Sentinel进程是用于监控redis集群Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器切换,保证系统高可用
  • 每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)Master、Slave定时发送消息,以确认对方是否存活,如果发现对方指定配置时间内未得到回应,则暂时认为对方已离线,也就是所谓的主观认为宕机主观:是每个成员具有的是独自的,而且可能相同可能不同意识)。英文名称Subjective Down,简称SDOWN
  • 主观宕机对应的有客观宕机。当哨兵群中的多数Sentinel进程在对Master主服务器做出SDOWN判断,并且通过Sentinel is-master-down-by-addr命令互相交流之后,得出的Master Server下线判断,这种方式就是客观宕机(客观是不依赖于某种意识,而是已经实际存在的一切事物)。英文名称是Objectively Down, 简称ODOWN
  • 通过一定的vote选举算法,从剩下slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移failover故障转移
  • Sentinel机制可以解决master和slave角色自动切换问题,但单点Master性能瓶颈问题无法解决,类似于MySQL中的MHA功能
  • Redis Sentinel中的Sentinel节点个数应该为大于等于3最好为奇数

哨兵机制能做什么?

  • 集群监控:负责监控redis master和redis slave进程是否正常工作
  • 消息通知:如果某个redis节点故障,那么哨兵就会发送消息作为报警通知给管理员
  • 故障转移:如果master节点挂掉了,会自动转移到slave节点
  • 配置中心:如果故障转移发生了,会通知client客户端新的master地址

什么是主观下线和客观下线?

主观下线

  • sentinel系统中其中一个sentinel认为redis集群某个redis宕机了或不可用,则会标记主观下线

客观下线

  • 如果被标记下线redis节点master节点,则还需要获得其他sentinel节点判断,如果超过法定数量投票,就会认为该master节点不可用,就会标记master节点客观下线

哨兵的三个定时监控

  • 监控1哨兵节点每隔10秒redis master和redis slave节点发送info指令,获取最新的拓扑结构,并更新自身保存的节点信息
  • 监控2哨兵节点每隔2秒redis指定频道上发送对master主节点状态的判断自身哨兵节点的信息其他哨兵节点也会订阅这个频道,来了解对master主节点状态的判断自身哨兵节点的信息
  • 监控3哨兵节点每隔1秒redis所有节点其他哨兵节点发送ping信息,进行心跳检测

master主节点下线后,怎么进行故障转移?

  • 这里主要有2步,首先是哨兵系统中会进行leader角色选举,再由leader哨兵去负责故障转移

leader哨兵的选举

  • 当master下线后,每个哨兵都可以选择自己作为leader,将请求发送其他哨兵
  • 其他哨兵接受到请求后,可以选择同意或者不同意(根据判定基础决定)
  • 如果最终某个哨兵节点获得了超过半数的投票,则该哨兵节点就会成为leader,负责故障转移

故障转移,选举新的master

  • 过滤掉leader哨兵断开连接时间比较redis节点
  • 优先选择replica-priority小的
  • 选择偏移量比较大的(复制的数据越多的
  • 运行id较小

执行故障转移

  • leader新master节点发送slave no one命令,让它断开与原master的连接,成为独立节点
  • leader其他slave从节点发送slave ip port指令,让它向新master节点进行同步

redis_53">客户端是和哨兵通信还是redis集群通信

  • 其实都有建立通信,情况是这样的:
  • client连接集群首先会连接sentinel系统,然后订阅相关的频道获取redis集群主从切换,切换进度,新master地址等信息
  • 拿到master地址后,则会与master建立连接
  • leader执行了故障转移,选举了新的master后,也会在客户端订阅的频道发送最新的master地址
  • client拿到最新的master地址后,与其建立连接

实验步骤

  • 所有阶段中关闭redis的安全模式

编辑sentinel.conf

protected-mode no  #关闭保护模式
port 26379    #监听端口
daemonize no   #前台模式
pidfile /var/run/redis-sentinel.pid   #sentinel进程pid文件
loglevel notice   #日志级别
logfile ""
dir /tmp
sentinel monitor mymaster 172.25.254.10 6379 2   #创建sentinel监控监控master主机,2表示必须得到2票
sentinel down-after-milliseconds mymaster 10000   #master中断时长,10秒连不上视为master下线
acllog-max-len 128
sentinel parallel-syncs mymaster 1   #发生故障转移后,每次开始同步新master数据的slave数量
sentinel failover-timeout mymaster 180000   #整个故障切换的超时时间为3分钟
sentinel deny-scripts-reconfig yes
  • 所有redis集群都要编辑
[root@redis-node1 ~]# vim /etc/redis/sentinel.conf

在这里插入图片描述

  • sentinel monitor:这是Redis Sentinel命令一部分,用于开始监控一个新的master主节点
  • mymaster:这是你给被监控master主节点起名字,可以是任意字符串,但在你的Sentinel配置中需要保持一致这个名字用于在Sentinel系统内部标识这个主节点
  • 172.25.254.10:这是被监控主节点IP地址Sentinel会使用这个地址来与主节点进行通信
  • 6379:这是被监控主节点端口号Redis默认使用6379端口
  • 2:这是Sentinel判定主节点是否客观下线objectively down所需Sentinel数量阈值)。只有至少2Sentinel判定主节点不可达时,主节点才会被认为客观下线,并触发故障转移流程通常建议设置为Sentinel总数半数以上,以确保判断可靠性

在这里插入图片描述
sentinel down-after-milliseconds mymaster 10000 这条命令用于配置Redis Sentinel对名为mymaster主节点故障检测时间。具体来说,它定义了Sentinel多长时间内无法从主节点接收到有效回复后,会将该主节点标记为主观下线subjectively down

  • 10000:这是超时时间的值单位毫秒。在这个例子中,它被设置为10000毫秒,即10秒
#将sentinel.conf发给node2
[root@redis-node1 ~]# scp /etc/redis/sentinel.conf root@172.25.254.20:/etc/redis/

#将sentinel.conf发给node3
[root@redis-node1 ~]# scp /etc/redis/sentinel.conf root@172.25.254.30:/etc/redis/

sentinel.conf.bak备份

[root@redis-node1 ~]# cp /etc/redis/sentinel.conf /etc/redis/sentinel.conf.bak

[root@redis-node2 ~]# cp /etc/redis/sentinel.conf /etc/redis/sentinel.conf.bak

[root@redis-node3 ~]# cp /etc/redis/sentinel.conf /etc/redis/sentinel.conf.bak

开启哨兵

  • 所有redis集群都开启哨兵模式
[root@redis-node1 ~]# redis-sentinel /etc/redis/sentinel.conf

在这里插入图片描述

  • 以上为前台启动,如果想后台启动,则可以将sentinel.conf中的daemonize设置为yes
#查看生成的配置
[root@redis-node1 ~]# vim /etc/redis/sentinel.conf

在这里插入图片描述

[root@redis-node2 ~]# redis-sentinel /etc/redis/sentinel.conf
[root@redis-node3 ~]# redis-sentinel /etc/redis/sentinel.conf

测试

  • master节点下线
[root@redis-node1 ~]# redis-cli shutdown

在这里插入图片描述
在这里插入图片描述

  • 我们发现node2成为master

在这里插入图片描述

  • node1上线
[root@redis-node1 ~]# /etc/init.d/redis_6379   start

在这里插入图片描述

  • node1上线后自动成为slave,然后会删除自己原来的所有数据,再去同步新master上的数据

在这里插入图片描述

  • 先关闭sentinel进程,在将之前备份的bak文件复制回来
#先关闭sentinel进程,在将之前备份的bak文件复制回来
[root@redis-node1 ~]# cp /etc/redis/sentinel.conf.bak /etc/redis/sentinel.conf
  • 虽然关闭sentinel进程,但是新master还是node2
#先关闭sentinel进程,在将之前备份的bak文件复制回来
[root@redis-node2 ~]# cp /etc/redis/sentinel.conf.bak /etc/redis/sentinel.conf
#先关闭sentinel进程,在将之前备份的bak文件复制回来
[root@redis-node3 ~]# cp /etc/redis/sentinel.conf.bak /etc/redis/sentinel.conf
  • 重新启动sentinel进程
[root@redis-node1 ~]# redis-sentinel /etc/redis/sentinel.conf

[root@redis-node2 ~]# redis-sentinel /etc/redis/sentinel.conf

[root@redis-node3 ~]# redis-sentinel /etc/redis/sentinel.conf

在这里插入图片描述

  • 所以只要node2不挂掉,那node2永远都是master

整个哨兵主从架构中可能会出现的问题

问题:

  • 生产环境中如果master和slave中网络出现故障,由于哨兵的存在会把master提出去,当网络恢复后master发现环境发生改变master就会把自己的身份转换成slavemaster变成slave后会把网络故障那段时间写入自己中的数据清掉,这样数据就丢失了

解决:

  • master被写入数据时会持续连接slavemater确保至少有2个slave才允许写入,如果slave数量少于2个便拒绝写入

临时设定重启redis后会失效

#在master中设定
[root@redis-node2 ~]# redis-cli
127.0.0.1:6379> config set min-slaves-to-write 2
127.0.0.1:6379> config get min-slaves-to-write
1) "min-slaves-to-write"
2) "2"

永久配置

#修改master的配置文件,添加一行就行
[root@redis-node2 ~]# vim /etc/redis/6379.conf
min-slaves-to-write 2

#重启redis,不会影响master
[root@redis-node2 ~]# /etc/init.d/redis_6379 restart
127.0.0.1:6379> config get min-slaves-to-write
1) "min-slaves-to-write"
2) "2"


127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
min_slaves_good_slaves:2
slave0:ip=172.25.254.30,port=6379,state=online,offset=290343,lag=1
slave1:ip=172.25.254.10,port=6379,state=online,offset=290343,lag=1
master_failover_state:no-failover
master_replid:96ab7241c9b4b11a1eff2b5eb86df14d5e3b38e7
master_replid2:fc90c49e90a38305862dd41717797f3baca3f8aa
master_repl_offset:290343
second_repl_offset:290288
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:290288
repl_backlog_histlen:56

http://www.niftyadmin.cn/n/5796798.html

相关文章

实验6-2 基于二叉链表存储结构实现二叉树的基本操作

题目:计算二叉树中的叶子结点个数 (1)如果二叉树为空,则叶子结点个数为0。 (2)如果二叉树只有根节点,则叶子结点个数为1 (3)左子树叶子结点数+右子树叶子结点数 一、原代码 #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define …

数据可视化echarts学习笔记

目录&#xff0c;介绍 知识储备 一端操作&#xff0c;多端联动的效果&#xff08;开启了多个网页&#xff0c;操作一端&#xff0c;多个网页的效果会跟着改变&#xff09; cmd命令控制面板返回上一级或上上级 在当前目录打开文件&#xff1a; cd 文件名 在Windows命令提示符&am…

[文献阅读] Unsupervised Deep Embedding for Clustering Analysis (无监督的深度嵌入式聚类)

文章目录 Abstract:摘要聚类深度聚类 KL散度深度嵌入式聚类(DEC)KL散度聚类软分配&#xff08;soft assignment&#xff09;KL散度损失训练编码器的初始化聚类中心的初始化 实验评估总结 Abstract: This week I read Unsupervised Deep Embedding for Clustering Analysis .It…

HTTP协议及安全防范

由于图片解析问题&#xff0c;可以点击查看 &#x1f449;&#x1f3fb; 博客原文 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;超文本传输协议是一个用于 Web 应用程序通信的应用层协议。它是一种客户端-服务器协议&#xff0c;客户端通过发送请求到服务器来获取…

Vue 单表 CRUD模板 前端

结合后端CRUD模板食用更佳 后端CRUD模板 js文件 指向了后端的方法 页面基本模板 import request from /utils/request // 查询关键词列表 export function page(param) {return request({url: /systemConfig/page,method: post,params: param}) }// 新增 export function ad…

2024年图像处理、多媒体技术与机器学习

重要信息 官网&#xff1a;www.ipmml.org 时间&#xff1a;2024年12月27-29日 地点&#xff1a;中国-大理 简介 2024年图像处理、多媒体技术与机器学习&#xff08;CIPMT 2024&#xff09;将于2024年12月27-29日于中国大理召开。将围绕图像处理与多媒体技术、机器学习等在…

RabbitMQ中的Topic模式

在现代分布式系统中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个广泛使用的开源消息代理&#xff0c;支持多种消息传递模式&#xff0c;其中 Topic 模式 是一种灵活且强大的模式&#xff0c;允许生产者…

C++简明教程(文章要求学过一点C语言)(12)

C 编程命名规范 一、引言 在 C 编程中&#xff0c;采用统一且清晰的命名规范对于代码的可读性、可维护性以及团队协作至关重要。良好的命名能够让代码“自解释”&#xff0c;使其他开发者&#xff08;包括未来的自己&#xff09;能够迅速理解代码的意图和功能&#xff0c;减少…