十四、Redis Cluster集群

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高可用的基石。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka 业务日志采集最佳实践

简介 Apache Kafka 是一个分布式流处理平台,主要用于构建实时数据流管道和应用程序。在收集业务日志的场景中,Kafka 可以作为一个消息中间件,用于接收、存储和转发大量的日志数据。将 Kafka 与其他系统(如 Elasticsearch、Flume、…

AtCoder Beginner Contest 353 A~E(F,G更新中...)

A.Buildings 题意 给出若干个建筑,每个建筑有一个高度,问,从第二个建筑开始,比第一个建筑高的建筑中编号最小的是多少?如果不存在,输出-1. 分析 边输入边比较即可,如果循环结束还未找到&…

【muzzik 分享】Cocos 物理帧同步

# 前言 之前没研究帧同步,这是我前端时间没上班时边玩边搞做的 Demo 研究成果,总共时间一周(实际2-3天),发布的目的也很简单,打破技术垄断,才能诞生更高端的技术成果。而且就算我没发这篇帖子&…

重生奇迹mu战士攻略有哪些

1、生命之光:PK前起手式,增加血上限。 2、雷霆裂闪:眩晕住对手,战士PK战士第一技能,雷霆裂闪是否使用好关系到胜负。 3、霹雳回旋斩:雷霆裂闪后可以选择用霹雳回旋斩跑出一定范围(因为对手下一招没出意外…

Mybatis技术内幕-基础支撑层

整体架构 MyBatis 的整体架构分为三层, 分别是基础支持层、核心处理层和接口层。 基础支持层 基础支持层包含整个MyBatis 的基础模块,这些模块为核心处理层的功能提供了良好的支撑。 解析器模块 XPathParser MyBatis提供的XPathParser 类封装了XPat…

SpringCloud使用Nacos作为配置中心实现动态数据源切换

一、Nacos-Server 了解Nacos可以直接阅读官方文档 使用Nacos,我们需要有Nacos-Server,此处就不使用官方提供的release版本了,而是自己编译,因为本来就是Java开发的,所以对于Javaer来说也没啥难度! git c…

记nrm管理仓库以及发布npm包

前言 记一次在公司创建私有库以及发布npm包,留下个脚印 一、nrm是什么? nrm是 npm 镜像源管理工具,用于快速地在不同的 npm 源之间切换。 二、使用步骤 1.全局安装nrm 代码如下(示例): npm install -…

Git系列:git diff使用技巧

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【智能算法】鹭鹰优化算法(SBOA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年,Y Fu受到自然界中鹭鹰生存行为启发,提出了鹭鹰优化算法(Secretary Bird Optimization Algorithm, SBOA)。 2.算法原理 2.1算法思想…

Elasticsearch查看集群信息,设置ES密码,Kibana部署

Elasticsearch查看集群信息,设置ES密码,Kibana部署 查看集群信息查看节点信息查看集群健康状态查看分片信息查看其他集群信息 Kibana部署安装设置ES密码 查看集群信息 查看节点信息 curl http://127.0.0.1:9200/_cat/nodes?v 参数说明: ip…

OpenGL导入的纹理图片错位

在OpenGL中导入图片的纹理照片的函数为 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, p_w, p_h, 0, GL_BGR, GL_UNSIGNED_BYTE, pic_data);其中p_w, p_h为图片的宽和高,pic_data为指向图片存储空间的的地址(unsigned char *类型) 在OpenGL中图片默认是4字节对齐的&…

Web开发小知识点(二)

1.关于取余 我在Dart语言里(flutter项目) int checkNum (10 - 29) % 10; 那么checkNum等于1 但是在Vue项目里 const checkNum (10 - 29) % 10;却等于-9 语言的特性不同,导致结果也不同,如果要想和Dart保持一致,…

vue3.0(六) toRef,toValue,toRefs和toRow,markRaw

文章目录 toReftoValuetoRefstoRowmarkRawtoRef和toRefs的区别toRaw 和markRaw的用处 toRef toRef 函数可以将一个响应式对象的属性转换为一个独立的 ref 对象。返回的是一个指向源对象属性的 ref 引用,任何对该引用的修改都会同步到源对象属性上。使用 toRef 时需…

[蓝桥杯 2021 国 ABC] 123(java)——前缀和,思维

目录 题目 解析 代码 这么久了,我终于能不看别人代码完整写出来了,呜呜呜。虽然过程也是很曲折。 题目 解析 这个题,找其中数列的规律,1,1,2,1,2,3,1,2,3,4,...,因此我们把拆分成行列,如下…

Java并发处理

Java并发处理 问题描述:项目中业务编号出现重复编号 生成编号规则:获取数据库表最大值,然后再做1处理,即为新编号(因为起始值是不固定的,还存在‘字符数据’格式,做了字典项可配置,所以不能直…

Ai 一键美术绘画文章,蓝海项目,流量巨大,盈利成效显著

今天我要向大家介绍一个全新的蓝海项目,那就是AI一键美术绘画文章。这个项目打破了传统的思维模式,更加吸引人的眼球,已经在各大网站上引发了大量的关注,轻松在抖音上热门也变得简单易行且稳定。 下载 地 址 : laoa…

PopClip for Mac 激活版:让文本处理更高效

还在为繁琐的文本处理而烦恼吗?PopClip for Mac来帮您解决!这款神器般的文本处理工具,能让您轻松应对各种文本处理任务。无论是写作、编程还是日常办公,PopClip for Mac都能助您一臂之力,让您的文本处理更高效、更便捷…

【基础绘图】 09.小提琴图

效果图: 主要步骤: 1. 数据准备:生成随机数组 2. 数据处理:计算四分位数、中位数、均值、最大最小值 3. 图像绘制:绘制小提琴图 详细代码:着急的直接拖到最后有完整代码 步骤一:导入库包及…

动态规划----股票买卖问题(详解)

目录 一.买卖股票的最佳时机: 二.买卖股票的最佳时机含冷冻期: 三.买卖股票的最佳时期含⼿续费: 四.买卖股票的最佳时机III: 五.买卖股票的最佳时机IV: 买卖股票的最佳时机问题介绍:动态规划买卖股票的最佳时机是一个经典的…

排序2——冒泡排序,快速排序(3种递归方式+3种非递归方式)

目录 1.交换排序 2.冒泡排序 2.1基本思路 1.1.2复杂度分析 3.快速排序 3.1基本思想 3.2Hoare版本(最初的) 3.2.1缺点 3.2.2优化 第一种——随机选key 第二种——三数取中 第三种——小区间优化 3.3挖坑版本(更好理解&#xff09…