当前位置: 首页 > news >正文

大聪明教你学Java | 带你了解 Redis 的三种集群模式

前言

🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。
🍊支持作者: 点赞👍、关注💖、留言💌~

前几天大聪明的好朋友大明白去面试,面试结束后大聪明就赶紧联系大明白,问问面试的结果如何👇

大聪明:兄弟,面试的咋样?顺利不 😝
大明白:前面倒是挺顺利的,但是面试官问出的最后一个问题却把我给难住了😥
大聪明:什么问题还给你难住了 🤔
大明白:面试官让我说说 Redis 的三种集群模式以及他们的优缺点😭
大聪明:没答上来没关系,我给你讲讲,后面再去面试的话就不怕被问住了,听我给你娓娓道来…

Redis 的三种集群模式

Redis 的常用的集群方式主要有以下三种,分别是主从复制模式哨兵模式Redis-Cluster集群模式,那么下面我们就分别了解一下这三种集群模式的优点与缺点。

主从复制模式

主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点(Master),后者称为从节点(Slave),数据的复制是单向的,只能由主节点到从节点。Redis 的主从复制模式一般是由一主一从(一个主节点+一个从节点)或一主多从(一个主节点+多个从节点)的形式来构成。主节点负责写操作,从节点负责读操作,从节点从主节点复制数据,通过这种方式也可以实现读写分离。

P.S. 各位小伙伴看完主从复制模式的介绍后是不是觉得有点熟悉?没错!和咱们之前提到的 MySQL 主从同步比较像,无论是 Redis 的主从复制模式,还是 MySQL 的主从同步,这二者的根源本质都是一样的~

传送门:大聪明教你学Java | 带你了解 Binlog 实现 MySQL 主从同步的原理及实现方式

下面我们一起看看主从复制的原理 👇

  • 从服务器连接主服务器,发送 SYNC 命令(即 sync command 命令),请求同步链接
  • 主服务器接收到 SYNC 命名后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令
  • 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令
  • 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照
  • 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
  • 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;(从服务器初始化完成)
  • 主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令(从服务器初始化完成后的操作)

不了解什么是 RDB 文件的小伙伴可以移步至《大聪明教你学Java | 带你了解 Redis 中 RDB 与 AOF 的区别》

了解了主从复制模式的概念和原理后,我们一起总结一下主从复制模式的优缺点:

🍊优点🍊

1、支持主从复制,主机会自动将数据同步到从机,可以进行读写分离,同时缓解了主库的压力。
2、Master Server 是以非阻塞的方式为 Slaves 提供服务。所以在 Master-Slave 同步期间,客户端仍然可以提交查询或修改请求;Slave Server 同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据。

🍊缺点🍊

1、由于 Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致部分读写请求失败,需要等待机器重启或者手动将某台从节点升级为主节点才能解决。而且在主机宕机时,宕机前部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。

我们看完主从复制模式后,可能有些小伙伴就发现了一些问题:主从复制模式下,当主节点宕机后,需要手动将某台从节点切换为主节点,这需要人工干预,不仅费时费力,而且还会造成一段时间内服务不可用,这个问题该如何解决呢🤔 接下来就需要请哨兵模式登场了…

哨兵模式

为了解决我们刚刚谈到的问题,Redis 2.8 中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。其实哨兵模式也是一种主从复制模式,只不过增加了哨兵的功能,哨兵的功能主要有两点:第一是监控主服务器和从服务器是否正常运行;第二是当主节点出现故障时自动将从节点转换为主节点。

哨兵的启动依赖于主从模式,所以须把主从模式安装好的情况下再去做哨兵模式,所有节点上都需要部署哨兵模式,哨兵模式会监控所有的 Redis 工作节点是否正常,当 Master (主节点)出现问题的时候,因为其他节点与主节点失去联系,因此会进行投票,投票过半就认为这个 Master (主节点)的确出现问题,然后会通知其他哨兵,并从 Slaves (从节点)中选取一个作为新的 Master(主节点)。既然涉及到了投票过半的要求,那么参与投票的哨兵就必须为单数,即整个运行哨兵的集群的数量​不得少于3个节点​。在选取新的主节点的过程中,我们又可以将整个过程细分为两步,分别为“选哨兵领导”和“由哨兵领导推举主节点”。

🍎 第一步:选哨兵领导 🍎

哨兵A: 哎哎哎!!!兄弟们,我发现主节点掉了啊!!!你们赶紧选我当头,我去选一个新的子节点来做主节点!!!
哨兵B: 额…行吧,我选你当头,虽然我很想当领导,但是也没啥经验呢,还是你来吧。
哨兵C: 不行!!我不支持你,我才是当领导的材料!!
哨兵A: 哨兵C你去一边子的,咱们就三个兄弟,我和哨兵B都支持,那我就是领导了😎

P.S. 如果此时有多个哨兵同时参选,则在等待任意时间后重新发起投票,直到选出了领头的

🍎 第二步:哨兵领导选择主节点 🍎

哨兵A: 我来看看以前的领导留下来的《如何选择主节点》里是怎么写的…翻书ing… 根据书里的记载,我需要按照健康性(哨兵发送ping命令后的响应时间长短,时间越短则越健康)、完整性(选择复制偏移量最大,也就是复制最完整的从节点)、优先级高低(选择配置文件中从节点优先级配置最高的,即replica-priority,其默认值为100)来进行主节点的挑选工作,如果有两个从节点都具备这三个条件的话,那就根据节点启动时分配的 run id 来决定谁做主节点(runid越小越有可能被选择为主节点)…
哨兵A: 还是查书有用啊,要不我还真不知道怎么干,我去选主节点啦~~

P.S. 选择主节点的过程又称为故障转移的过程

这里有一点是需要注意的,哨兵的下线分为两种,分别是主观下线(我认为你掉线了)和客观下线(我们认为你掉线了)。每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次 ping 命令做一次心跳检测。如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的)。当超过半数哨兵节点认为该主节点主观下线了,这样就客观下线了。客观下线是针对于主节点来说的概念,也就是说只有发生了客观下线,才会执行我们上面所说的两个步骤;如果从节点和哨兵节点发生故障,被哨兵主观下线后,则不会再有后续的客观下线和故障转移操作。

通过上面的讲解,我们也就可以总结出哨兵模式的优点了:哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有,同时使用哨兵模式后主从节点可以自动切换,可以让系统更健壮,可用性更高。

Redis-Cluster集群模式

Redis 的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在 Redis3.0 上加入了 Cluster 模式,实现的 Redis 的分布式存储,即每台 Redis 节点(Node)上存储不同的内容,很大程度上节约了内容。需要注意的是,集群中的节点也是分为主节点和从节点的,只有主节点负责读写请求和集群信息的维护,而从节点只进行主节点数据和状态信息的复制。Redis-Cluster采用无中心结构,它有以下三个特点 👇

① 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
②节点的失效(下线)是通过集群中超过半数的节点检测失效时才生效。
③ 客户端与 Redis 节点直连,不需要中间代理层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

接下来我们一起看看 Redis-Cluster 集群模式的工作流程:

在 Redis 的每一个节点上,都有这么两个小东西,一个是插槽(slot),它的的取值范围是:0-16383,另一个就是cluster,可以理解为是一个集群管理的插件。当 Redis 拿到了需要存取的 key 时,Redis 会根据 CRC16 算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。为了保证高可用,Redis-Cluster 集群引入了主从模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。

虽说 Redis-Cluster 集群引入了主从模式,但是也带来了一个问题:如果集群中具有A、B、C三个节点,如果节点B失败了,整个集群就会因缺少5461-10922这个范围的插槽而不可使用;如果为每个节点添加一个从节点A1、B1、C1整个集群便有三个Master节点和三个slave节点组成,当在节点B失败后,那么集群选举B1位为主节点继续服务。但是当B和B1都失败后,集群将不可用。

Redis-Cluster 集群模式中用到了高效的的 Gossip 通信协议,关于 Gossip 协议的介绍,各位小伙伴可以移步至《大聪明教你学Java | 面试官:请你说说 Redis 为什么这么快?》

有些小伙伴看到这里可能会产生一个疑问:为什么插槽数是16384个呢?为什么不能是65535或者是其他数值呢?其实关于这个问题,作者已经给了我们一个回复👇

The reason is:

  1. Normal heartbeat packets carry the full configuration of a node, that can be replaced in an idempotent way with the old in order to update an old config. This means they contain the slots configuration for a node, in raw form, that uses 2k of space with16k slots, but would use a prohibitive 8k of space using 65k slots.
  2. At the same time it is unlikely that Redis Cluster would scale to more than 1000 mater nodes because of other design tradeoffs.

So 16k was in the right range to ensure enough slots per master with a max of 1000 maters, but a small enough number to propagate the slot configuration as a raw bitmap easily. Note that in small clusters the bitmap would be hard to compress because when N is small the bitmap would have slots/N bits set that is a large percentage of bits set.

用一句话总结出来就是:由于 Redis 节点之间通讯会相互交换槽信息,那如果槽过多(意味着网络包会变大),网络包变大,就意味着会过度占用网络的带宽,同时作者认为 Redis 集群中节点数不会超过1000个,所以作者就取了16384这个数,即可以将数据合理打散至 Redis 集群中的不同实例,又不会在交换数据时导致带宽占用过多。

链接:https://github.com/redis/redis/issues/2576

在这里插入图片描述

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

你在被打击时,记起你的珍贵,抵抗恶意;
你在迷茫时,坚信你的珍贵,抛开蜚语;
爱你所爱 行你所行 听从你心 无问东西

相关文章:

大聪明教你学Java | 带你了解 Redis 的三种集群模式

前言 🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。 🍊支持作者: 点赞👍、关注💖、留言&#x1f4…...

Java中异常(异常的处理方式(JVM默认的处理方式、自己处理(灵魂四问)、抛出异常(throws、throw))、异常中的常见方法、小练习、自定义异常)

编译时异常:在编译阶段,必须要手动处理,否则代码报错(提醒程序员检查本地信息) 运行时异常:在编译阶段是不需要处理的,是代码运行时出现的异常(代码出错而导致程序出现的问题&#…...

液氮恒温器概述

恒温器是直接或间接控制一个或多个热源和冷源来维持所要求的温度的一种装置。 恒温器要实现这种功能,就必须具有一个敏感元件和一个转换器,敏感元件量度出温度的变化,并对转换器产生所需的作用。转换器把来自敏感元件的作用转换成对改变温度…...

Shiro核心——Realm

RealmRealm的作用Realm的实现Realm的配置实例在Shiro中,Realm是一个非常灵活和强大的安全组件,它能够与各种数据源进行集成,满足各种安全需求。通过实现自定义的Realm,我们可以轻松地定制身份验证、授权和加密逻辑,实现…...

开发钉钉微应用,实现免登+调试

1.创建h5微应用 https://open.dingtalk.com/document/orgapp/develop-org-h5-micro-applications 根据里面的三个步骤,创建h5微应用 2.免登之前必须要先进行JSAPI的授权 文档说明: https://open.dingtalk.com/document/orgapp/jsapi-authentication 根据文档中的说明 步骤…...

0308java基础-注解,反射

一,注解 1.什么是注解: Annotation是从jdk5.0开始引入的新技术作用: 不是程序本身,可以对程序作出解释可以被其他程序读取格式: 以注释名在代码中存在,还可以添加一些参数值SuppressWarnings(value"…...

【鸿蒙应用ArkTS开发系列】- 页面跳转及传参

先看下效果图 大致实现的功能点: 从Indext页面跳转到Second页面,传递两个参数,一个字符串,一个数量;Second获取Index页面传递的数据;Second页面点击返回弹窗;Second页面返回携带参数数据&#…...

StringBuilder 类

Java StringBuilder类是一个可变字符串缓冲区,它提供了丰富的方法可以方便地进行字符串操作。与Java StringBuffer类类似,Java StringBuilder类的主要作用是优化字符串的拼接操作,提高代码的效率。在本篇文章中,我们将详细介绍Jav…...

kubectl-k8s用户切换

kubernetes默认使用$HOME/.kube/config配置文件。可以在配置文件中定义多个USER和Cluster的上下文。所以就有两种方式切换用户同一个config中,切换不同用户上下文切换不同的config配置文件同config切换不同用户上下文查看config文件kubeconfig config view查看当前上…...

【面试题】三道面试题让你掌握JavaScript中的执行上下文与作用域以及闭包

前言大厂面试题分享 面试题库前后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库大家好,笔者呢最近再回顾JavaScript知识时,又看到了JavaScript的一些较为常见的内容,仔细看了之后发现…...

计算机网络-- 应用层(day08)

计算机网络两种方式 网络应用程序运行再处于网络边缘的不同端系统上,通过彼此间的通信来共同完成某项任务。 开发一种新的网络应用首先要考虑的问题就是网络应用程序在各种端系统上的组织方式和它们之间的关系。 目前流行的主要有以下两种: 客户/服务器…...

English Learning - L2-5 英音地道语音语调 弹力双元音 [ɪə] [ʊə] [eə] 2023.03.6 周一

English Learning - L2-5 英音地道语音语调 弹力双元音 [ɪə] [ʊə] [eə] 2023.03.6 周一朗读节奏元音的长度元音发音在清辅音和浊辅音前的区别元音发音跟后面浊辅音节数的区别元音在重读音节中复习大小元音发音对比/ʌ/ 舌中音/ɒ/ 舌后音/ʊ/ 舌后音/ɪ/ 舌前音[ɑ:] VS […...

SpringBoot——统一功能处理

处理登陆拦截 上一片博客中讲到SpringAOP可以对页面进行拦截,我们可以用SpringAOP实现对登陆的拦截 但是由于拦截需要HttpSession对象,并且之后还需要页面重定向,因此在实际应用中,并不用SpringAOP进行登陆拦截,而是…...

ORACLE SQL格式化小数点

ORACLE SQL格式化小数点 select CONCAT(TO_CHAR(0.00100,‘990.999’),‘%’) as a0 , CONCAT(TO_CHAR(1100,‘990.999’),‘%’) as a1 , CONCAT(TO_CHAR(0.236100,‘990.999’),‘%’) as a2 , CONCAT(TO_CHAR(0.0200100,‘990.999’),‘%’) as a3 , CONCAT(TO_CHAR(1.0310…...

【信息学奥数】—— 第一部分 C++语言 知识总结

【信息学奥数】—— 第一部分 C语言 知识总结C语言一、C语言入门二、顺序结构程序设计运算符和表达式常量和变量标准数据类型数据输入输出三、控制结构程序设计if语句switch语句四、循环结构程序设计for语句while语句do-while语句五、数组一维数组二维数组字符数组六、函数七、…...

video层级过高,以及界面使用多个video时,在安卓APP上同时播放的问题(uniapp)

1、video层级过高的问题 问题一: 我的界面由于是自定义导航栏,所以使用video时,上滑界面video会直在最上层,盖着 头部导航栏 解决方法:使用cover-view,自定义头部使用cover-view替换view 问题二:自定义…...

C++基础了解-14-C++ 字符串

C 字符串 一、C 风格字符串 C 风格的字符串起源于 C 语言,并在 C 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。 下面的声明和初始化创建了一个 RUNOOB …...

浅谈几种网络攻击及攻防原理

HTTP Flood攻击 https://zhuanlan.zhihu.com/p/337399808 HTTP Flood攻击是针对Web服务在第七层协议发起的攻击。第七层主要是应用层,是一些终端的应用,比如(各种文件下载)、浏览器、QQ等,可以将其理解为在电脑屏幕上可…...

Kafka消息中间件(Kafka与MQTT区别)

文章目录KafkaKafka重要原理Topic 主题Partition 分区Producer 生产者Consumer 消费者Broker 中间件Offset 偏移量Kafka与mqtt区别Kafka Kafka是一个分布式流处理平台,它可以快速地处理大量的数据流。Kafka的核心原理是基于发布/订阅模式的消息队列。Kafka允许多个…...

Go垃圾回收原理

术语介绍 赋值器:说白了就是你写的程序代码,在程序的执行过程中,可能会改变对象的引用关系,或者创建新的引用。 回收器:垃圾回收器的责任就是去干掉那些程序中不再被引用得对象。 STW:全称是stop the word,GC期间某个阶段会停止…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

LLM基础1_语言模型如何处理文本

基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...