十四、Redis Cluster集群

news2024/12/24 9:17:06
Redis Cluster是Redis提供的一个分布式解决方案,在3.0推出。Redis Cluster可以自动将数据分片分布到不同的master节点上,同时提供了高可用的支持,当某个master节点挂了之后,整个集群还是可以正常工作。

1、为什么要用Redis Cluster?

前面十三章讲解了Redis中的哨兵模式。了解了Redis基于读写分离实现的主从架构。同时也知道了当Redis的master节点发生故障时,Sentinel是如何执行故障转移的。
的确,在数据上有从节点做副本数据备份;可用性上,有Sentinel保证master发生故障时,自动执行故障转移。
那么我们就会有疑问,为什么还需要Redis Cluster呢?
首先,Redis Sentinel实际上就是基于主从复制,在主从复制中,从节点的数据完全来源于master节点。
image.png
那么,假设现在master节点的内存只有4G,那么slave节点最多也就只能存储4G的数据。而且在前面第十三章中也介绍过,在主从复制的架构中读写是分离,也就是说我们可以横向增加slave节点的数量来提升Redis的读并发能力,但是写能力存储能力是无法扩展的,就只能是master节点的承载上限。
因此,当我们只存储4G的数据时,基于主从复制和Sentinel的高可用架构完全没得问题。但是当我们的数据量达到16G、64G、1TB呢?在现在互联网的业务中,只要公司的体量大,我感觉必然会面临海量数据缓存问题。

这就是为什么要引入Redis Cluster的原因。

2、Redis Cluster是什么

Redis Cluster我们可以很简单的理解为n个主从架构一起对外提供服务。Redis Cluster要求最少3个master才能组成一个集群,同时每个master至少有一个slave节点。
image.png
这样一来,如果一个主从能够存储32G数据,那么2个主从就可以存储64G的数据。如果有更大量的数据,只需要加相应数量的主从即可。
在主从架构中,我们知道可以通过增加slave节点的数量来提供Redis的读请求并发能力。那么Redis Cluster是如何做的呢?虽然每个master节点都挂了至少一个slave节点,但是slave节点只是做数据的备份作用,所有的读写请求都由master节点提供

3、节点负载均衡

从上面我们知道,在Redis Cluster中只有master节点对外提供读写能力,且有多个master,每个master上的存储的数据都不一样。那么Redis Cluster是如何知道哪个数据存储到哪个master上的呢?

3.1、哈希算法

一般的负载均衡算法,基本上会采用哈希算法
image.png
首先对key计算出一个hash值,然后用hash值对master的数据量取模。由此就可以将key均匀的分布到每个master节点上。这就是简单的哈希算法的实现。但是Redis Cluster并没有采用这种实现方式。而是采用了一个类一致性哈希算法的实现方式。
对于为什么没有采用哈希算法原因是:假如此时有一台master节点挂掉了,那么此时会导致Redis中的所有缓存失效(基本上所有数据都查不到)。
那么为什么呢?假如现在有3台master节点,那么之前的哈希算法应该是hash % 3,如果此时有一台master节点挂掉了,那么此时的哈希算法就应该是hash % 2。由于取模的基数不一样了,那么势必会影响的之前存储的所有数据。

3.2、一致性哈希算法

我们上面说到的哈希算法,是对master节点数量进行取模。而一致性哈希算法,是对232 取模,也就是值的范围在[0-232-1]。一致性哈希算法将其范围抽象成一个圆环,使用CRC16算法计算出来的哈希值会落到圆环的某个地方。
而且,我们的Redis实例也分布在圆环上,我们在圆环上按照顺时针的顺序找到第一个Redis实例,那么这个key存储的就是在这个实例上。
image.png
举个例子:假设我们有A、B、C三个实例按照如图的方式分布在圆环上,此时计算出来的hash值对应在D的位置,那么我们按照顺时针的顺序,就能够找到这个key应该分配的Redis实例B。同理计算出来的位置在E,那么对应的Redis实例就是A。
即使这个时候Redis实例B挂掉了也不会影响到A、C两个实例。
image.png
假如此时B节点挂掉了,那之前计算出来的位置D的key,按照顺时针顺序找到节点C。相当于把节点B的流量转移到节点C上,原来节点A、C的流量没有影响。
这就是一致性哈希算法,能够在我们后续删除或者添加节点的时候,不影响其他节点。

3.3、一致性哈希算法的虚拟节点机制

但是一致性哈希算法还是有点问题,例如当们的Redis节点按照如下分布时:
image.png
如果按照Redis节点上图分布时,明显数据落在节点A上的几率更大,其次落到节点C的几率最小。这样一来导致整个集群的数据存储不平衡,A、B节点的负载较高,节点C的资源利用不足,所以为了解决这个问题,引入了虚拟节点机制。
image.png
在圆环中增加了对应节点的虚拟节点,然后完成了虚拟节点到真实节点的映射。假设现在计算出来的结果是位置D,那么按照顺时针顺序,我们找到的第一个节点就是虚拟节点C#1,由于有虚拟节点到真实节点的映射关系,所以数据最终会落到真实节点C上。
通过增加虚拟节点的方式,使ABC三个节点在圆环上分布更加均匀,平均了落在每个节点上的概率。这样就解决了上面提到的节点分布不均匀导致的数据分布不均匀的问题。这就是一致性哈希算法的虚拟节点机制。

4、Redis Cluster采用的算法

Redis Cluster 采用的是类一致性哈希算法。
一致性哈希算法是对232取模,而Redis Cluster则是对214(也就是16384)取模。Redis Cluster将自己分成了16384个Slot(槽位)。通过CRC16计算出来的哈希值,会对16384取模,取模之后得到的值就是对应的槽位,然后每个redis节点都会负责处理一部分的槽位,就像下标所示:

节点处理槽位
A0-5000
B5001-10000
C10001-16383
每个Redis实例都会维护一份**slot-Redis节点**的映射关系,但是如果你在节点A上设置了某个key,但是通过CRC16计算的槽位是节点B维护的,那么就会提示你去节点B上进行操作。

image.png

5、Redis Cluster如何做到高可用?

现在我们想一个问题:如果Redis Cluster中的某个master节点挂了,它是如何保证集群自身的高可用的?如果我们想在集群里扩容节点,新扩容的节点它应该负责哪些槽位?

5.1、集群如何扩容?

Redis Cluster可以很方便的横向扩容,那当新的节点加入进来时,它是如何获取对应的slot的呢?
答案是通过**reshard(重新分片)**来实现,reshard可以将已经分配给某个节点的任意数量的slot迁移给另一个节点。在Redis内部是通过redis-trib负责执行的。可以理解为Redis其实已经封装好了所有命令,而redis-trib负责向获取slot节点和被转移slot的节点发送命令来实现reshard。

假设我们想集群中加入一个新节点D,而此时集群内已经有A、B、C三个节点。
此时redis-trib会向A、B、C三个节点发送迁移出槽位的请求,同时会向D发送准备导入槽位的请求,做好准备之后A、B、C这三个节点就开始执行迁移,将对应的slot的所有键值迁移到目标节点D。最后redis-trib会向集群中的所有主节点发送槽位变更信息。

5.2、高可用故障转移

Redis Cluster中保证集群高可用的思路和Redis Sentinel如出一辙。
简单来说,针对节点A,如果某个节点认为节点A挂了,那么此时就是主观宕机,而如果集群内超过半数的节点都认为节点A挂了,那么此时A就会标记为客观宕机
一旦节点A被标记为客观宕机,那么集群就会开始故障转移。其余正常运行的master节点会进行投票选举,从节点A的slave节点中选出一个,将其切换为新的master节点对外提供服务。当某个slave节点获得超过半数的master节点的投票,就成功当选。
image.png
当选成功后,新的master节点会执行slaveof no one来让自己停止复制节点A,使自己成为master节点。然后将A节点负责的slot,全部转移给自己,然后向集群发送PONG消息来广播自己的最新状态。

按照一致性哈希算法的思想,如果某个节点挂了,那么就会沿着那个圆环,按照顺时针找到遇到的第一个Redis实例。
而对于Redis Cluster,某个key它其实是不用关心它最终是去哪个Redis实例,它只要关心自己属于哪个slot,不论你节点怎么迁移,最终还是只需要找到对应的slot即可,然后在找到slot关联的节点。

6、gossip协议

gossip:留言、八卦、小道消息。

gossip协议:就是Redis Cluster各个节点之间交换数据、通信所采用的一种协议。
gossip在最初提出是为了解决分布式数据库中,各个副本节点的数据同步问题。但是随着技术的发展,gossip后续也被广泛用与信息扩散、故障检测等等。
Redis Cluster就是用gossip来实现自身的
信息扩散
的。
image.png
很简单,就像图里那样,每个Redis节点每秒都会向其他节点发送PING,然后被PING的节点会回一个PONG。

6.1、gossip协议消息类型

Redis Cluster中,节点之间的消息类型分为5种,分别是MEET、PING、PONG、FAIL和PUBLISH。

消息类型消息内容
MEET给某个节点发送MEET消息,请求接收消息的节点加入到集群。(新的节点加到集群)
PING每隔一秒钟,选择5个最久没有通信的节点,发送PING消息,检测对应的节点是否在线;同时还有一种策略:如果某个节点的通信延迟大于cluster-node-time的值的一半,就会立即给该节点发送PING消息,避免数据交换延迟太久。
PONG当节点收到MEER或者PING消息后,会回一个PONG消息给对方,代表自己收到了MEET或者PING消息。同时,节点也可以主动发送PONG消息向集群中广播自己的信息,让其他节点获取到自己的最新消息。就像完成故障转移之后的新的master向集群发送PONG消息一样。
FAIL用于广播自己的对某个节点的宕机判断,假设当前节点对节点A判断为宕机,那么就会立即向Redis Cluster广播自己对于节点A的判断,所有收到消息的节点就会对A节点进行标记。
PUBLISH用于向指定的Channel发送消息,某个节点收到PUBLISH消息之后会直接在集群内广播,这样一来,客户端不论连接到任何节点都能订阅这个Channel。

6.2、gossip的优劣

优点
扩展性网络可以允许节点的任意增加和减少,新增加的节点的状态最终会与其他节点一致。
容错性由于每个节点都持有一份完整的元数据,所以任何节点宕机都不会影响gossip的运行。
健壮性与容错性类似,由于所有节点都持有数据,地位平等,是一个去中心化的设计。任何节点都不会影响到服务的运行。
最终一致性当有新消息需要传递时,消息可以快速的发送到所有节点,让所有节点都拥有最新的数据。
gossip可以在O(logN)轮就可以将信息传播到所有节点,为什么是O(logN)呢?因为每次PING,**当前节点都会带上自己的信息外加整个Cluster的1/10数量的节点信息**,一起发送出去。

7、总结

总的来说,Redis Cluster相当于是把Redis的主从架构Sentinel继承在一起,从Reids Cluster的高可用机制、判断故障转移以及执行故障转移的过程,都和主从、Sentinel相关。这也就是为什么说,主从是Redis高可用的基石。

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

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

相关文章

Spring底层入门(十一)

1、条件装配 在上一篇中,我们介绍了Spring,Spring MVC常见类的自动装配,在源码中可见许多以Conditional...开头的注解: Conditional 注解是Spring 框架提供的一种条件化装配的机制,它可以根据特定的条件来控制 Bean 的…

stm32f103c8t6之4x4矩阵按键

基于普中精灵开发板 1、矩阵按键原理 当我们需要使用较多的按键时,单片机的IO口可能不够用,这是就需要使用矩阵按键。 对应IO口如下: 步骤解析: 1、全部按键都没有按下时,全行IO为低电平(全列对应的IO设置为下拉低…

1060: 无向图的最大度计算

解法&#xff1a; #include<iostream> #include<vector> using namespace std; int arr[100][100]; int main() {int n, max 0;cin >> n;vector<int> sum(n, 0);for (int i 0; i < n; i) {for (int j 0; j < n; j) {cin >> arr[i][j];…

Nginx(简洁版)

基本配置 worker_processes 1; //默认为1&#xff0c;表示开启一个业务进程 events //事件驱动模块&#xff08;&#xff09;{worker_connections 1024; //单个业务进程可接受连接数 } http{include mime.types; // 引入http mime类型&#xff08;在外部已经定义好&#xff0c…

数据链路层(详细版)【02】

接 数据链路层&#xff08;详细版&#xff09;【01】 文章目录 四、以太网MAC层&#xff08;一&#xff09;MAC地址组成&#xff08;1&#xff09;48位MAC地址格式&#xff08;2&#xff09;单播地址 & 多播地址 & 广播地址&#xff08;3&#xff09;全球管理 & 本…

ctfshow web271--web273

web271 laravel5.7反序列化漏洞 define(LARAVEL_START, microtime(true));/* |-------------------------------------------------------------------------- | Register The Auto Loader |-------------------------------------------------------------------------- | |…

OFDM802.11a的FPGA实现(十三)加窗(含verilog和matlab代码)

原文链接&#xff08;相关文章合集&#xff09;&#xff1a;OFDM 802.11a的xilinx FPGA实现 1.前言 添加循环前缀后,对数据还要进行加窗(Windowing)操作。加窗操作可以使OFDM 符号在带宽之外的功率谱密度下降得更快。 2.加窗 对OFDM符号“加窗”意味着令符号周期边缘的幅度…

WHAT - CSS Animationtion 动画系列(二)

目录 一、循环波浪二、关键帧呼应三、关键帧顺接四、利用 transform-origin 做拉伸五、大元素可拆分多个小元素联动六、预留视觉缓冲七、随机感&#xff1a;动画周期设置八、抛物线&#xff1a;两个内外div实现x和y向量运动 今天我们主要学习动画实现要素。 一、循环波浪 利用…

RAG讲解

现有的LLM已经具备了理解、生成、逻辑和记忆能力&#xff0c;RAG(Retrieval Augmented Generation)则是为其套上外挂&#xff0c;使LLM能够访问训练数据来源之外的权威知识库&#xff0c;并生成领域特定的内容&#xff0c;而无须重新训练模型。 RAG的优势 经济高效&#xff1a…

【简单介绍下Sass】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

HTML标签快速入门

文章目录 一、HTML语法规范1.1 基本语法概述1.2 标签关系 二、HTML基本结构标签2.1 第一个HTML网页2.2 基本结构标签总结 三、网页开发工具3.1 文档类型声明标签3.2 lang 语言种类3.3 字符集3.4 总结 四、HTML常用标签4.1 标签语义4.2 标题标签\<h1> - \<h6>&#…

RuvarOA协同办公平台 多处 SQL注入漏洞复现

0x01 产品简介 RuvarOA办公自动化系统是广州市璐华计算机科技有限公司采用组件技术和Web技术相结合,基于Windows平台,构建在大型关系数据库管理系统基础上的,以行政办公为核心,以集成融通业务办公为目标,将网络与无线通讯等信息技术完美结合在一起设计而成的新型办公自动…

NodeMCU ESP8266 操作 SSD1306 OLED显示屏详解(图文并茂)

文章目录 1 模块介绍2 接线介绍3 安装SSD1306驱动库4 源码分析4.1 硬件兼容性4.2 可能存在的问题总结1 模块介绍 我们将在本教程中使用的OLED显示屏是SSD1306型号:单色0.96英寸显示屏,像素为12864,如下图所示。 OLED显示屏不需要背光,这在黑暗环境中会产生非常好的对比度。…

Curator分布式锁

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 分布式锁服务宕机,…

实现二叉树的基本操作

博主主页: 码农派大星. 关注博主带你了解更多数据结构知识 1我们先来模拟创建一个二叉树 public class TestBinaryTreee {static class TreeNode{public char val;public TreeNode left;public TreeNode right;public TreeNode(char val) {this.val val;}}public TreeNode …

Web入门——三栏布局页面

前置知识 内外边距 内边距(padding)&#xff1a; padding是元素边框与其内容之间的空间。也就是说&#xff0c;如果你给一个元素设置了内边距&#xff0c;这个空间会作为元素内容与元素边框之间的缓冲区域。设置内边距会使元素本身变大。例如padding:10px就创建了10像素的空间…

每日OJ题_贪心算法四④_力扣397. 整数替换

目录 力扣397. 整数替换 解析代码 力扣397. 整数替换 397. 整数替换 难度 中等 给定一个正整数 n &#xff0c;你可以做如下操作&#xff1a; 如果 n 是偶数&#xff0c;则用 n / 2替换 n 。如果 n 是奇数&#xff0c;则可以用 n 1或n - 1替换 n 。 返回 n 变为 1 所需…

计算机网络复习-传输层

概念 传输层是进程与进程之间的通信使用端口(Port)来标记不同的网络进程端口(Port)使用16比特位表示(0~65535) UDP协议详解 UDP&#xff1a;用户数据报协议数据报&#xff1a;应用层传输过来的一个完整的数据不合并&#xff0c;不拆分 UDP的头部 UDP特点 UDP是无连接协…

picoCTF-Web Exploitation-Trickster

Description I found a web app that can help process images: PNG images only! 这应该是个上传漏洞了&#xff0c;十几年没用过了&#xff0c;不知道思路是不是一样的&#xff0c;以前的思路是通过上传漏洞想办法上传一个木马&#xff0c;拿到webshell&#xff0c;今天试试看…

【计算机网络】物理层 通信基础、奈氏准则、香农公式 习题2

下列说法中正确的是( )。 A. 信道与通信电路类似&#xff0c;一条可通信的电路往往包含一个信道 B.调制是指把模拟数据转换为数字信号的过程 C. 信息传输速率是指通信信道上每秒传输的码元数 D.在数值上&#xff0c;波特率等于比特率与每符号所含的比特数的比值 信息传输速率&a…