Redis从入门到精通(十四)Redis分布式缓存(二)Redis哨兵集群的搭建和原理分析

文章目录

    • 前言
    • 5.3 Redis哨兵
      • 5.3.1 哨兵原理
        • 5.3.1.1 集群的结构和作用
        • 5.3.1.2 集群监控原理
        • 5.3.1.3 集群故障恢复原理
      • 5.3.2 搭建哨兵集群
      • 5.3.3 RedisTemplate
        • 5.3.3.1 搭建测试项目
        • 5.3.3.2 场景测试

前言

Redis分布式缓存系列文章:

Redis从入门到精通(十三)Redis分布式缓存(一)RDB和AOF持久化、Redis主从集群的搭建与原理分析

5.3 Redis哨兵

Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。

5.3.1 哨兵原理

5.3.1.1 集群的结构和作用

哨兵的结构如图:

哨兵的作用如下:

  • 监控:Sentinel会不断检查master和slave是否按预期工作;
  • 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后,将作为新的master的slave节点加入集群。
  • 通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端。
5.3.1.2 集群监控原理

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:

  • 主观下线:如果某Sentinel节点发现某Redis实例未在规定时间响应,则认为该Redis实例主观下线。
  • 客观下线:若超过指定数量(quorum)的Sentinel都认为该Redis实例主观下线,则该Redis实例客观下线。quorum值最好超过Sentinel实例数量的一半。

5.3.1.3 集群故障恢复原理

一旦发现master故障,Sentinel需要在salve中选择一个作为新的master,选择依据是这样的:

  • 首先会判断slave节点与master节点断开时间长短,如果超过指定值(down-after-milliseconds * 10)则会排除该slave节点;
  • 然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举;
  • 如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高;
  • 最后是判断slave节点的运行id大小,越小优先级越高。

当选出一个新的master后,Sentinel会进行角色切换,切换流程是这样的:

  • Sentinel给备选的slave1节点发送slaveof no one命令,让该节点成为master;
  • Sentinel给所有其它slave发送slaveof <ip> <port>命令,让这些slave成为新master的从节点,开始从新的master上同步数据;
  • 最后,Sentinel将故障节点标记为slave,当故障节点恢复后会自动成为新的master的slave节点。

5.3.2 搭建哨兵集群

这里将搭建一个三节点形成的Sentinel集群,来监管之前的Redis主从集群。同样,可以在一台虚拟机上创建3个不同端口(27001、27002、27003)的Sentinel实例,来模拟Sentinel集群。

搭建步骤:

  • 1)在/usr/local/redis目录下创建3个目录,名称分别是s1、s2、s3:

  • 2)分别在s1、s2、s3目录下创建配置文件sentinel.conf,添加下面的内容:
# 端口
port 27001
# 以后台进程启动
daemonize yes
sentinel announce-ip "192.168.146.128"
# 指定主节点信息# mymaster 主节点名称,自定义,任意写# 192.168.146.128 7001 主节点的IP和端口# 2 选举master时的quorum值
sentinel monitor mymaster 192.168.146.128 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
# 文件目录
dir "/usr/local/redis/s1"
# 日志文件目录
logfile "/usr/local/redis/s1/sentinel_27001.log"

s1、s2、s3的配置文件中port、dir、logfile应改成各自对应的,其余配置可保持一致。

  • 3)启动3个Sentinel实例**
/usr/local/bin/redis-sentinel /usr/local/redis/s1/sentinel.conf
/usr/local/bin/redis-sentinel /usr/local/redis/s2/sentinel.conf
/usr/local/bin/redis-sentinel /usr/local/redis/s3/sentinel.conf

启动完成后,可查看Sentinel进程如下:

  • 4)测试哨兵作用

尝试让master节点7001宕机,查看Sentinel 27001的日志:

查看7002的日志:

查看7003的日志:

查看此时Redis集群的状态:

至此,Redis哨兵集群搭建完成,并正常工作。

5.3.3 RedisTemplate

在Sentinel集群监管下的Redis主从集群,其节点的角色会因为自动故障转移而发生变化,Redis的客户端必须感知这种变化,及时更新连接信息。

Spring的RedisTemplate底层利用lettuce实现了节点的感知和自动切换。

5.3.3.1 搭建测试项目

下面搭建一个SpringBoot项目来进行测试,步骤如下:

  • 1)引入依赖
<!--pom.xml--><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>
</dependencies>
  • 2)编写配置文件
// src/main/resources/application.ymlserver:port: 8082
spring:application:name: redis_learning_clusterredis:# Redis主从集群的主节点host: 192.168.146.128port: 7001password: 123321# Redis哨兵集群配置sentinel:master: mymasternodes:- 192.168.146.128:27001- 192.168.146.128:27002- 192.168.146.128:27003lettuce:pool:max-active: 10max-idle: 10min-idle: 1time-between-eviction-runs: 10sjackson:default-property-inclusion: non_null# 修改日志级别为Debug,这样才能查看到RedisTemplate具体连接了哪个实例
logging:level:root: DEBUG
  • 3)编写主启动类
// com.star.redis.cluster.RedisClusterApp@SpringBootApplication
public class RedisClusterApp {public static void main(String[] args) {SpringApplication.run(RedisClusterApp.class, args);}@Beanpublic LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {// 配置读写策略// MASTER 从master节点读取// MASTER_PREFERRED 优先从master节点读取,master不可用才读取replica节点// REPLICA 从slave(replica)节点读取// REPLICA_PREFERRED 优先从slave(replica)节点读取,所有的slave都不可用才读取master节点return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);}}
  • 4)编写Controller类
// com.star.redis.cluster.controller.RedisController@RestController
@RequestMapping("/redis")
public class RedisController {@Resourceprivate StringRedisTemplate stringRedisTemplate;@GetMapping("/get/{key}")public String get(@PathVariable String key) {return stringRedisTemplate.opsForValue().get(key);}@GetMapping("/set/{key}/{value}")public String set(@PathVariable String key, @PathVariable String value) {stringRedisTemplate.opsForValue().set(key, value);return "success";}
}
5.3.3.2 场景测试

首先检查一下当前Redis主从集群的状态:

此时7003实例是master节点,7001、7002实例是slave节点。

场景一:调用/redis/set/name/Rose接口,由日志可知写操作由master节点7003实例完成:

场景二:调用/redis/get/name接口,由日志可知读操作由slave节点7002实例完成:

场景三:如果此时master节点7003宕机了,Sentinel会重新选举一个master,这里选择的是7001:

场景四:再次调用/redis/set/name/Rose接口,由日志可知写操作由master节点7001实例完成,意味着RedisTemplate感知到了主从节点的变化:

场景五:再次调用/redis/get/name接口,由日志可知读操作由slave节点7002实例完成:

至此,Redis哨兵集群搭建完毕,且正常工作。

本节完,更多内容请查阅分类专栏:Redis从入门到精通

感兴趣的读者还可以查阅我的另外几个专栏:

  • SpringBoot源码解读与原理分析(已完结)
  • MyBatis3源码深度解析(已完结)
  • 再探Java为面试赋能(持续更新中…)

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

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

相关文章

一个开源嵌入式USB设备协议栈:FelisUSB

概述 Felis USB 是一个嵌入式USB协议栈。它不依赖于软件系统支持&#xff0c;可以轻量级迁移使用。 Felis USB is an USB stack for embedded system. See introduction in English here. 源码链接&#xff1a;season-studio/FelisUSB:null_C - GitCode开源社区 为什么开发Feli…

AI时代的新星:Devin AI 工程师的崛起

近日&#xff0c;人工智能领域掀起了一股新浪潮&#xff0c;一家成立不到两个月的初创公司Cognition推出了一款名为Devin的全球首位AI工程师。这款AI工程师引起了业界的高度关注&#xff0c;其独特的特点和能力使其成为软件开发领域的一颗耀眼之星。 Devin并非仅仅是一款编写代…

欧盟网络安全局:公共数据空间中的个人数据保护设计(下)

三、应用场景分析:健康—医药用途 2020年欧盟发布欧盟医药战略,旨在应对制药行业面临的各种机遇和挑战,以确保欧盟公民对于药品的可获得性、可负担性和可持续性。[4]报告将药品数据空间作为一种可能的手段,旨在支持数据使用者对于药品市场供应情况和药品功效的研究和分析。…

Java复习第十七天学习笔记(转发、重定向,GET,POST),附有道云笔记链接

【有道云笔记】十七 4.3 转发、重定向、Get、POST、乱码 https://note.youdao.com/s/GD5TRksQ 一、转发 转发&#xff1a;一般查询了数据之后&#xff0c;转发到一个jsp页面进行展示 req.setAttribute("list", list); req.getRequestDispatcher("student_lis…

大厂面试:获取字符串的全排列

一、概念 现有一个字符串&#xff0c;要打印出该字符串中字符的全排列。例如输入字符串abc&#xff0c;则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。 可以基于回溯法来解决这个问题。 二、代码 public class Permutation {//输出字符串str的全…

算法 第38天 动态规划1

509 斐波那契数 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n…

权限修饰符,代码块,抽象类,接口.Java

1&#xff0c;权限修饰符 权限修饰符&#xff1a;用来控制一个成员能够被访问的范围可以修饰成员变量&#xff0c;方法&#xff0c;构造方法&#xff0c;内部类 &#x1f47b;&#x1f457;&#x1f451;权限修饰符的分类 &#x1f9e3;四种作用范围由小到大(private<空着…

SV-704XT 100W网络有源音柱 校园广播音柱

SV-704XT 100W网络有源音柱 一、描述 SV-704XT是深圳锐科达电子有限公司的一款壁挂式网络有源音柱&#xff0c;具有10/100M以太网接口&#xff0c;可将网络音源通过自带的功放和喇叭输出播放&#xff0c;其采用防水设计&#xff0c;功率100W。SV-704XT作为网络广播播放系统的终…

【算法】斐波那契数列第n位 - 去重递归/双指针迭代

题目 给定n&#xff0c;求斐波那契数列第n位的数值。 斐波那契数列&#xff1a;0 1 1 2 3 5 8 13 …… 每个数等于前面两个数相加&#xff0c;第n位等于第(n - 1)位加上第(n - 2)位。 原理 去重递归 使用递归的方式计算出结果&#xff0c;但使用一个数组保存已经计算出来的值…

java 将 json 数据转为 java 中的对象

一、准备 json 数据 {"name": "mike","age": 17,"gender": 1,"subject": ["math","english"] }二、对应的java对象 package com.demo.controller;import lombok.Data; import java.util.List;Data pu…

什么是感知器 怎么学习感知器

什么是感知器&#xff1f; 感知器是一种简单的人工神经网络算法&#xff0c;也是最早的神经网络单元之一&#xff0c;由Frank Rosenblatt于1957年提出。它被设计用来进行二元分类&#xff0c;即判断输入数据属于哪一类&#xff08;例如&#xff0c;是或否&#xff09;。感知器…

蓝桥杯练习题 —— 01字串(python)

for i in range(32):number ((7 - len(str(bin(i)))) * "0") str(bin(i))[2:]print(number) 所用方法 以下代码用于实现十进制转二进制、八进制、十六进制&#xff1a; for i in range(100, 1000):a i // 100 # 百位b i % 100 // 10 # 十位c i % 10 …

回溯算法先导

撤销当前的操作 使用原因及解决的问题 基本上暴力搜索的问题 适用于 组合问题 [1,2,3,4] 两位数的组合有哪些切割问题 给定字符串,求切割方式使其字串都是回文子串子集问题 求 [1,2,3,4] 的子集排列组合 组合(不强调顺序)棋盘问题 如何理解回溯法 抽象为一个树形结构 回溯…

华为OD-C卷-最长子字符串的长度(一)[100分]

题目描述 给你一个字符串 s,首尾相连成一个环形,请你在环中找出 o 字符出现了偶数次最长子字符串的长度。 输入描述 输入是一个小写字母组成的字符串 输出描述 输出是一个整数 备注 1 ≤ s.length ≤ 500000s 只包含小写英文字母用例1 输入 alolobo输出 6说明 最长子字…

Python模块pyttsx3添加语音包

查询现有语音包信息:脚本import pyttsx3engine = pyttsx3.init() voices = engine.getProperty(voices) for voice in voices:print("Voice:")print(" - ID: %s" % voice.id)print(" - Name: %s" % voice.name)print(" - Languages: %s&qu…

MySQL 04-EMOJI 表情与 UTF8MB4 的故事

拓展阅读 MySQL View MySQL truncate table 与 delete 清空表的区别和坑 MySQL Ruler mysql 日常开发规范 MySQL datetime timestamp 以及如何自动更新&#xff0c;如何实现范围查询 MySQL 06 mysql 如何实现类似 oracle 的 merge into MySQL 05 MySQL入门教程&#xff0…

MySQL基础练习题:习题21-25

这部分主要是为了帮助大家回忆回忆MySQL的基本语法&#xff0c;数据库来自于MySQL的官方简化版&#xff0c;题目也是网上非常流行的35题。这些基础习题基本可以涵盖面试中需要现场写SQL的问题。 列出在部门sales工作的员工的姓名&#xff0c;假定不知道销售部的部门编号 sele…

产品思维训练 | 熊孩子任性打赏从产品角度有哪些方法可以规避?

本周话题&#xff1a; 抖音回应10岁儿童打赏主播10万&#xff1a;已全额退款。正值特殊时期&#xff0c;小朋友们花费在直播APP中的时间也不少。 对于打赏等行为&#xff0c;当然需要家长加强监督&#xff0c;除此之外&#xff0c;产品方面可以做什么措施&#xff0c;压制住胡…

【JS】获取接口返回 EventStream 结构的数据(即接收读取 stream 流)

文章目录 EventStream 是一种服务器推送的数据格式&#xff0c;可以用于实时数据传输。 接口返回的示例图 获取示例&#xff1a; // 这里的 url 为虚拟的&#xff0c;仅供演示用 fetch(https://test.cn.com/api/agent/2, {method: POST,headers: {Content-Type: applicatio…

Docker部署前后端项目

使用Docker部署前后端项目的全面指南 在现代软件开发中&#xff0c;Docker已经成为了部署应用程序的一种流行方式。它提供了一种轻量级的、可移植的、自给自足的解决方案&#xff0c;可以在不同的环境中一致地运行应用程序。本文将详细介绍如何使用Docker来部署一个包含前端和…