redis 集群 底层原理以及实操

news2024/12/30 2:56:07

前言

上篇我们讲解了哨兵集群是怎么回事

也说了对应的leader选举raft算法

也说了对应的slave节点是怎么被leader提拔的

主要是比较优先级 比较同步偏移量 比较runid等等

今天我们再说说,其实哨兵也有很多缺点

虽然在master挂了之后能很快帮我们选举出新的master

但是对于单个master承受的压力过大的情况还是没有得到很好的解决

因此,我们就推出了新的技术  集群cluster

于是我们也就放弃了原有的哨兵操作

下面我们慢慢介绍

结构

首先我们也是先看看原来的哨兵架构

再来看看今天要介绍的集群架构

这里对应master之间是数据共享的

至于为什么我们下面慢慢介绍

由于集群自带故障迁移,这里也是自然取代了哨兵

首先我们先介绍几个基本的概念

分片

这里分片的意思就是对应的每个节点负责一部分的槽位数据

一个集群负责所有的数据

一个节点就负责一片片区的数据

槽位

上面我们提到的一片片区的基本单位就是槽位

是由16384个槽位组成的

注:这里建议节点数不要超过1k

上述的架构可以这样理解

哈希算法

我们如何找到对应的槽位呢?

通过一次CRC16算法再&0x3FFF即可

哈希映射有哪些 方式呢???

1.哈希取余分区算法

简单有效

将对应的哈希值取模一个机器数量即可

缺点就是扩容比较困难

我们需要将所有数据key进行一次rehash的操作

2.一致性哈希分区算法

首先由一个重要的概念称之为哈希环

也就是将所有数据首位相连成一个一致性哈希环

假设是0-65535

这里0和65536指向的就是同一块位置

逻辑图如下

这样我们也就得到了一个所有哈希值的全量集

接着将对应的服务器ip进行对应的映射

最后就是对应的key进行hash了

就是顺时针找到的第一个节点就负责存储这一个键值对

优点是容错性好,缺失一个节点也能直接使用下一个遇见的redis节点进行存储

扩展性好,假设需要加上一个节点x,就只需要移动一小块区域的数据

如上图 我们只需要移动对应的a到x的数据即可

但是缺点也是存在的

很可能出现数据倾斜的问题

也就是说头重脚轻,分配不均匀的情况

于是我们就使用了哈希槽的方式解决问题

3.哈希槽分区算法

就是我们之前说的将16384个哈希槽分给不同的节点来保存

这里主要就是一个使用CRC16(key) 再进行了一次取模16384的操作

主要架构如下

为啥是16384???

为啥是16384个槽位呢

主要是因为以下原因

1.首先客户端每隔一段时间会给服务器发送心跳包,心跳包中就有槽位的数据

如果需要65536个槽位这里的数据量就达到了8K,但是如果是16384个槽位这里的数据就只有2k,这样的性能更好不容易导致网络阻塞

2.官网声明不可以使用超过1000个节点

因为节点过多就会导致传输数据的失真等等,也是不可取的

这里16384个槽位也是足够使用的

3.对于文件的压缩

发送的数据包如果太大就不方便压缩了

这里16384个槽位slot是刚刚好的

数据丢失

注:redis集群并没有保证数据的强一致性

假设我给1号机器写入数据还没来得及同步给从机就挂掉了

从机即使上位也无法得到之前的数据

集群搭建

首先我们在myredis下面创建新的cluster文件夹存放对应的配置文件

mkdir -p /myredis/cluster   这里-p就是父目录不存在也会创建  

我们三台虚拟机每台放两个配置文件

分别对应一主一从

对应的配置文件如下

这里我们使用的是从6381开始的6个redis节点

bind 0.0.0.0
daemonize yes
protected-mode no
port 6382
logfile "/myredis/cluster/cluster6382.log"
pidfile /myredis/cluster6382.pid
dir /myredis/cluster
dbfilename dump6382.rdb
appendonly yes
appendfilename "appendonly6382.aof"
requirepass 111111
masterauth 111111
cluster-enabled yes
cluster-config-file nodes-6382.conf
cluster-node-timeout 5000

在六个redis节点都启动之后我们开始创建集群

使用如下命令,注意结合自身ip 使用ifconfig可以查看

redis-cli -a abc123 --cluster create 
--cluster-replicas 1 192.168.188.136:6381 192.168.188.136:6382 
192.168.188.137:6383 192.168.188.137:6384 
192.168.188.138:6385 192.168.188.138:6386
这里replicas 1 就是每个主机配置一个从机 后面对应主从关系 使用任意一台vm进行操作即可

接下来直接yes即可

出现对应的配置文件即算配置成功

我们可以使用

cluster nodes 查看集群状态

注意这里不同的机器对应的槽位不同

所以set k1 v1 很可能会失败

而k2v2会成功

这是因为登入的是1号节点 而对应计算的槽位是由5号节点管理的

我们只需要在登录的时候在最后加上一个-c 以集群形式登录

此时遇到哪个集群就会自动跳转到对应的ip端口进行操作了

redis-cli -a abc123 -p 6381 -c

这里可以理解为路由/重定向

容灾

先说结论,主机挂了从机会上位

此时主机再回来也只能当从机了

下面是具体演示

手动shutdown6381

使用cluster nodes查看情况

我们发现对应的6384上位了

此时重启6381只能当小弟了

我们还可以进行对应的恢复

让6381继续当老大,6384继续当小弟

此时只需要登录6381进行对应的操作即可

cluster failover

此时6381就可以重回master

扩容

下面演示扩容节点

我们先在192.168.138第三台vm下创建两个配置文件

并启动对应的redis

加入集群只需要执行以下命令

找6381当做引路人即可

此时我们会发现虽然添加节点成功但是没有分配槽位

检查一下集群状态

redis-cli -a abc123 --cluster check 192.168.188.136:6381

我们需要进行reshard进行分配槽位

redis-cli -a abc123 --cluster reshard 192.168.188.138:6387

因为现在是4个节点所以分配一个节点4096个槽位

我们需要之前check的6387的id号

然后输入all

进行对应的reshard

在进行一次check查看对应的状态

最后为6387分配从节点

redis-cli -a abc123 --cluster add-node 192.168.188.138:6388 192.168.188.138:6387 --cluster-slave --cluster-master-id e03b3d6631033baa0961653ebec70800f6bf0fec

最后检查一下结构

最后四主四从也就搭建完成了

缩容

虽然基本上用不到,但是咱们主打一个完整性

首先清楚6388

使用上面的check指令获取对应的id

redis-cli -a abc123 --cluster del-node 192.168.188.138:6388  20dd91501451051961745a005f580858db6f7a2e

删除之后对应的子节点可以再查看一下

然后得执行reshard将对应的slot槽位分配回去

为了方便起见我们直接全分配给6381号机器即可


redis-cli -a abc123 --cluster reshard 192.168.188.136:6381

直接全部分配写4096

然后选择6381号机器的id

对应的done即可

此时我们再进行一次check

我们发现6387已经变成salve了

对应的槽位也清零了

最后进行删除节点操作

redis-cli -a abc123 --cluster del-node 192.168.188.138:6387 e03b3d6631033baa0961653ebec70800f6bf0fec

批处理操作

我们知道不同的key k1 k2 k3会被分配到不同的slot上

所以进行批处理查询操作是会报错的

如果我们想进行批处理

可以使用通配符将几个key映射为一组

类似于以下操作

我们在cluster.c的源文件中也可以找到对应的

我们发现redis会使用通配符{}中间的元素进行CRC算法

其他操作

redis还有一个重要参数

就是当假设分区1的主从节点都宕机了之后

我们对外还会不会进行服务暴露???

默认是yes 也就是不服务暴露的  但是我们也是可以设置服务暴露的

但是这时候就会有一些数据是不可访问的

重要的三个集群命令

cluster nodes  
查看节点情况


cluster countinkeysinslot slotId  
查看slot是否被占用


cluster keyslot k1
查看key使用的slot是啥
也就是进行了一次CRC16算法并取余16384

示例如下

说明1236槽位没有存放数据

说明k123会存放在4255槽位上

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

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

相关文章

计算机毕业设计 | SpringBoot个人博客管理系统(附源码)

1,绪论 1.1 背景调研 在互联网飞速发展的今天,互联网已经成为人们快速获取、发布和传递信息的重要渠道,它在人们政治、经济、生活等各个方面发挥着重要的作用。互联网上发布信息主要是通过网站来实现的,获取信息也是要在互联网中…

【Qt】初识

一、使用Label显示Hello World 1.ui设计 可以在Qt Designer中拖拽方式进行创建 2.代码方式 在myqwidget.cpp文件中添加下列代码 二、对象树 我们在堆上创建了QLabel类的对象。但是我们没有去delete,这样会产生内存泄漏吗? 答案是不会。label对象会在…

2024 京麟ctf -MazeCodeV1

文章目录 检查代码思路一个字节的指令注意附上S1uM4i佬们的exp https://www.ctfiot.com/184181.html 检查 代码 __int64 __fastcall check_solve(char *a1) {__int64 result; // rax__int64 v2; // rax__int64 index_step; // rax__int64 v4; // rax__int64 v5; // rax__int64…

LPDDR6带宽预计将翻倍增长:应对低功耗挑战与AI时代能源需求激增

在当前科技发展的背景下,低能耗问题成为了业界关注的焦点。国际能源署(IEA)近期报告显示,日常的数字活动对电力消耗产生显著影响——每次Google搜索平均消耗0.3瓦时(Wh),而向OpenAI的ChatGPT提出的每一次请求则消耗2.9…

继电器的选型和英应用

如何保证信号的稳定? 怎么消除继电器触点的电弧? 危害: 继电器的触点在动作时容易产生电弧,电弧具有热效应容易导致触点烧蚀粘接,缩短继电器的寿命,并且产生电弧的过程中会对外进行电磁辐射,…

鸿蒙开发接口图形图像:【WebGL】

WebGL WebGL提供图形绘制的能力,包括对当前绘制图形的位置、颜色等进行处理。 WebGL标准图形API,对应OpenGL ES 2.0特性集。 说明: 开发前请熟悉鸿蒙开发指导文档: gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md…

Django 做migrations时出错,解决方案

在做migrations的时候,偶尔会出现出错。 在已有数据的表中新增字段时,会弹出下面的信息 运行这个命令时 python manage.py makemigrationsTracking file by folder pattern: migrations It is impossible to add a non-nullable field ‘example’ to …

Spring OAuth2:开发者的安全盾牌!(下)

上文我们教了大家如何像海盗一样寻找宝藏,一步步解锁令牌的奥秘,今天将把更加核心的技巧带给大家一起学习,共同进步! 文章目录 6. 客户端凭证与密码模式6.1 客户端凭证模式应用适用于后端服务间通信 6.2 密码模式考量直接传递用户…

小短片创作-理论知识(三)

1、抗锯齿 1.相机移动的时候出现锯齿 2.当1个像素在三角形边缘的时候,可能取值为白色,也可能取值为黑色,表现出来就是闪烁,或锯齿 3.如果我们通过超采样将1个像素变成4个像素进行计算,得到的结果就会更准确&#x…

文件IO(二)

文件IO(二) 标准IO缓冲类型全缓冲行缓冲不缓冲 打开文件fopen 操作文件按字符读写(fgetc fputc)按行读写(fgets fputs)按块(对象)读写(fread fwrite)按格式化读写(fscanf…

【考研数学】李艳芳900比李林880难吗?值得做吗?

差不多,只能说基础没搞好刷这两个都很费劲 李艳芳900题把每个章节题目划分为ABC三个难度级别,题目选取的难度较大也比较新颖,计算量也非常接近考研趋势,原创性很高,比较适合过完一轮的同学继续做补充和强化 880算是比…

深度学习:手撕 RNN(2)-RNN 的常见模型架构

本文首次发表于知乎,欢迎关注作者。 上一篇文章我们介绍了一个基本的 RNN 模块。有了 这个 RNN 模块后,就像搭积木一样,以 RNN 为基本单元,根据不同的任务或者需求,可以构建不同的模型架构。本节介绍的所有结构&#…

(函数)判断素数(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//声明素数判断函数&#xff1b; void prime(int number);int main() {//初始化变量值&#xff1b;int number 0;//获取用户输入的数据&#xff1b;printf(&quo…

有趣的css - 列表块加载动效

大家好&#xff0c;我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;今天分享的是用 css 打造一个极简的列表块加载动效。 最新文章通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页面渲染效果 整…

渗透测试工具Cobalt strike-2.CS基础使用

三、结合metasploit,反弹shell 在kali中开启使用命令开启metasploit msfconsole ┌──(root㉿oldboy)-[~] └─# msfconsole --- msf6 > use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp --- msf6 exploit(multi/handler) > show …

excel表格里怎样不删除0,又不显示0呢?

在单元格里不显示0&#xff0c;大体上有这么几种方法&#xff1a; 1.设置单元格自定义格式 选中数据区域&#xff0c;鼠标右键&#xff0c;点一下设置单元格格式&#xff0c;选中数字&#xff0c;自定义&#xff0c;在右侧的类型栏&#xff0c;设置格式&#xff1a; [0]&quo…

FinRobot:一个由大型语言模型(LLM)支持的新型开源AI Agent平台,支持多个金融专业AI Agent

财务分析一直是解读市场趋势、预测经济结果和提供投资策略的关键。这一领域传统上依赖数据&#xff0c;但随着时间的推移&#xff0c;越来越多地使用人工智能&#xff08;AI&#xff09;和算法方法来处理日益增长的复杂数据。AI在金融领域的作用显著增强&#xff0c;它自动化了…

ch3运输层--计算机网络期末复习(持续更新中)

运输层位于网络层之上 运输层协议提供的某些服务受到网络层协议的限制。比如,时限和带宽保证。 运输层也提供自己的特殊服务。比如,可靠数据传输服务,安全性服务。 网络层:两个主机之间的逻辑通信 运输层:两个进程之间的逻辑通信 网络地址:主机的标识(IP地址) 传输地址: …

3.Linux系统环境搭建

一、虚拟化机&#xff1a;指的是通过虚拟化技术将一台计算机分为多台逻辑计算机。注&#xff1a;虚拟机共用CPU和内存资源。 二、虚拟机用途&#xff1a; 1.搭建学习环境&#xff1a;例如在同一间实验室里&#xff0c;物理机Windows系统&#xff0c;虚拟机可以用Linux系统。 …

【网络运维的重要性】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…