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

redis 集群 底层原理以及实操

前言

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

也说了对应的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槽位上

相关文章:

redis 集群 底层原理以及实操

前言 上篇我们讲解了哨兵集群是怎么回事 也说了对应的leader选举raft算法 也说了对应的slave节点是怎么被leader提拔的 主要是比较优先级 比较同步偏移量 比较runid等等 今天我们再说说,其实哨兵也有很多缺点 虽然在master挂了之后能很快帮我们选举出新的master 但是对于单个ma…...

MVC架构中的servlet层重定向404小坑

servlet层中的UserLoginServlet.java package com.mhys.servlet; /*** ClassName: ${NAME}* Description:** Author 数开_11* Create 2024-05-29 20:32* Version 1.0*/import com.mhys.pojo.User; import com.mhys.service.UserService; import com.mhys.service.impl.UserSer…...

Java-RabbitMQ

RabbitMQ使用场景 1、跨系统异步通信 2、多应用之间解耦 3、应用内流程同步变异步 4、整体架构即采用消息驱动 5、应用内部解耦 RabbitMQ内部角色 角色简介生产者消息创建者消费者消息接收者代理RabbitMQ本身,用于存储转发消息,快递功能 RabbitMQ有哪…...

ABAP 在增强中COMMIT

前言 呃,又是很磨人的需求,正常情况下是不允许在增强中COMMIT的,会影响源程序本身的逻辑,但是这个需求就得这么干… 就是在交货单增强里面要再调用一次交货单BAPI,通过SO的交货单自动创建STO的交货单,如果…...

【UML用户指南】-02-UML的14种图

1、结构图 1、类图(class diagram) 展现了一组类、接口、协作和它们之间的关系。 在面向对象系统的建模中所建立的最常见的图就是类图。类图给出系统的静态设计视图。 包含主动类的类图给出系统的静态进程视图。构件图是类图的变体。 2、对象图&a…...

Linux驱动开发笔记(二) 基于字符设备驱动的I/O操作

文章目录 前言一、设备驱动的作用与本质1. 驱动的作用2. 有无操作系统的区别 二、内存管理单元MMU三、相关函数1. ioremap( )2. iounmap( )3. class_create( )4. class_destroy( ) 四、GPIO的基本知识1. GPIO的寄存器进行读写操作流程2. 引脚复用2. 定义GPIO寄存器物理地址 五、…...

三品软件:打造高效安全的图文档管理体系

在数字化转型的浪潮中,工程设计单位和企业设计部门面临着电子图文档管理的巨大挑战。随着电子图纸和文档数量的激增,如何有效组织、管理和共享这些资源,成为提升工作效率和保障信息安全的关键。本文将探讨当前图文档管理面临的问题&#xff0…...

N1 one-hot编码

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊# 前言 前言 onehot编码在机器学习比较常见,例如推荐系统中类别变量的处理等。 onehot 编码简介 One-hot编码(one-hot encoding&…...

数据库基础+增删查改初阶

数据库基础增删查改初阶 一。数据库操作 1.概念: 一个mysql服务器上有很多的表,把有关系的表放在一起就构成了一个数据集合,此时称为“数据库”,一个mysql1服务器上可以有多个这样的数据库 2.创建数据库: create …...

大模型日报2024-05-29

大模型日报 2024-05-29 大模型资讯 大型语言模型在金融预测中将超越人类分析师 摘要: 新研究表明,大型语言模型如ChatGPT在金融预测方面表现优于人类专家,为交易策略提供了宝贵的见解。这意味着未来这些模型将在金融领域发挥更重要的作用,提升…...

如何摆脱打工人任人宰割的命运

那就是为自己打工。 要有自己的思想,自己的目标,有自己的方向,坚决的非常自信的去执行它。 这样才是活出属于自己的人生,活出自己的精彩。 当然,这是在你已经比周围人优秀的情况下,至少是你觉得你比他们…...

“图片在哪”、“我是temunx”、“变成思维导图用xmindparser”gpt给出文本变字典

需求 我的意思是什么 分类清单“图片在哪 我是temunx变成思维导图 用xmindparser用 shell 画思维导图 x mind,可以 /storage/emulated/0/字体/黑体.ttf 保存/storage/emulated/0/print/图片/input图纸/完整代码 给个文本内容”任务清单 调整语言顺序文不对题的…...

【LeetCode】【5】最长回文子串

文章目录 [toc]题目描述样例输入输出与解释样例1样例2 提示Python实现动态规划 个人主页:丷从心 系列专栏:LeetCode 刷题指南:LeetCode刷题指南 题目描述 给一个字符串s,找到s中最长的回文子串 样例输入输出与解释 样例1 输入…...

主播们直播时的美颜是如何实现的?集成第三方美颜SDK方案详解

很多人问小编,主播们直播时的美颜效果是如何实现的呢?接下来,我将为您详细介绍美颜功能的实现原理。 一、美颜功能的基本原理 通过对图像进行实时处理,达到美化人脸的效果。其主要技术包括: 1.人脸检测与关键点定位 …...

Leetcode - 131双周赛

一,3158. 求出出现两次数字的 XOR 值 本题是一道纯模拟题,直接暴力。 代码如下: class Solution {public int duplicateNumbersXOR(int[] nums) {int ans 0;long t 0;for(int x : nums){if(((t>>x)&1) 1){ans ^ x;}else{t | (…...

【CSharp】判断目录以及文件是否存在

【CSharp】判断目录以及文件是否存在 1.背景2.判断目录3.判断文件1.背景 我们在进行磁盘IO的时候进行需要判断目录、文件是否存在,根据判断结果再做进一步的操作。 其中判断目录是否存在,涉及Directory.Exists(String) 方法; 命名空间:System.IO 方法功能:确定给定路径是…...

kali基本扫描工具(自带)

免责声明:本文仅做技术交流与学习...请勿非法破坏... 详细用法: 命令 -h/百度/翻译 fping 用法 hostlist 文件里面为ip fping -a -q -f hostlist -a 只看存活的 fping -g 202.100.1.1 202.100.1.255 -a -q > Ahost 输出到Ahost文件上 nping nping -c 1 201.100.2.155-244 …...

与MySQL的初相遇

🌎初识MySQL 注:本文SQL语句只为了验证猜想,不会也不要紧。 文章目录: MySql开端 认识数据库       什么是数据库       主流数据库       MySQL的本质 MySQL基础使用       连接mysql服务器     …...

详解Spring IoCDI(一)

目录 1.什么是IoC 2.IoC应用场景(案例分析) 2.1传统程序开发 2.2问题分析 2.3解决方案 2.4IoC 优势 3. DI概念 4.IoC详解 4.1Bean的存储 4.2Controller(控制器存储) 4.3获取Bean 4.4Bean相关注解 1.什么是IoC Spring…...

Android 14 - 绘制体系 - 概览

从Android 12开始,Android的绘制系统有结构性变化, 在绘制的生产消费者模式中,新增BLASTBufferQueue,客户端进程自行进行queue的生产和消费,随后通过Transation提交到SurfaceFlinger,如此可以使得各进程将缓…...

【RAG论文】文档树:如何提升长上下文、非连续文档、跨文档主题时的检索效果

RAPTOR Recursive Abstractive Processing for Tree-Organized RetrievalICLR 2024 Stanfordhttps://arxiv.org/pdf/2401.18059 RAPTOR(Recursive Abstractive Processing for Tree-Organized Retrieval)是一种创建新的检索增强型语言模型,它…...

【前端每日基础】day27——小程序开发

小程序开发详细介绍 基本概念 小程序:小程序是一种无需下载安装即可使用的应用。用户通过微信搜索或扫描二维码即可打开小程序。小程序具有触手可及、用完即走、体验良好的特点。 组成部分: WXML:用于描述页面的结构。 WXSS:用于…...

【C语言】指针速览

指针速览 指针1.野指针与空指针2. 空类型指针 void *3. 指针常量4. 常量指针5. 指向常量的指针常量6. 指针操作数组6.1 数组名作为函数参数 7. 多级指针8. 函数指针8.1 函数指针数组 最后 指针 指针就是内存的字节单元编号地址,指针变量就是存放地址的变量。 1.野…...

Java基础学习:深入解析Java中的位运算符

在Java中,位运算符用于对整数类型的值进行位运算。以下是Java中的位运算符: 位与(&):两位都为1时,结果为1,否则为0。 位或(|):两位中有1个为1,结果为1。 位非(~):位的反&#…...

9.Redis之list类型

list相当于链表、数据表 1.list类型基本介绍 列表中的元素是有序的"有序"的含义,要根据上下文区分~~有的时候,谈到有序,指的是"升序","降序”有的时候,谈到的有序,指的是, 顺序很关键~~如果把元素位置颠倒,顺序调换.此时得到的新的 List 和之前的 Li…...

Git 的安装和使用

一、Git 的下载和安装 目录 一、Git 的下载和安装 1. git 的下载 2. 安装 二、Git 的基本使用-操作本地仓库 1 初始化仓库 1)创建一个空目录 2)git init 2 把文件添加到版本库 1)创建文件 2)git add . 3)g…...

大模型时代的具身智能系列专题(五)

stanford宋舒然团队 宋舒然是斯坦福大学的助理教授。在此之前,他曾是哥伦比亚大学的助理教授,是Columbia Artificial Intelligence and Robotics Lab的负责人。他的研究聚焦于计算机视觉和机器人技术。本科毕业于香港科技大学。 主题相关作品 diffusio…...

基于springboot+vue的社区医院管理服务系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...

车载电子电器架构 —— 智能座舱标准化意义

车载电子电器架构 —— 智能座舱标准化意义 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消…...

Compose在xml中使用滑动冲突处理

一、背景 在现有Android项目中使用Compose可能存在滑动冲突问题,例如 SmartRefreshLayoutCoordinatorLayoutComposeView(ComposeView这里又是一个LazyColumn) 二、解决方案 官方介绍:https://developer.android.google.cn/develop/ui/compose/touch-inp…...