Redis 全景图(1)--- 关于 Redis 的6大模块
这是我第一次尝试以长文的形式写一篇 Redis 的总结文章。这篇文章我想写很久了,只是一直碍于我对 Redis 的掌握没有那么的好,因此迟迟未动笔。这几天,我一直在看各种不同类型的 Redis 文章,通过阅读这些文章,引发了我对于 Redis 这个大知识点的很多思考。我看过的一篇又一篇的文章都帮助着将我脑子里我学过的 Redis 的零散知识点整合在一起,从而构建一个 Redis 全局系统观,帮助着我用一个全局的方式看待 Redis 这个存储系统。接下来,我计划用文字的方式,将我脑子里的 Redis 蓝图一一描绘出来。
Redis?什么是 Redis?Redis 就是一个键值对数据库。所以,当别人跟你说 Redis 的时候,你的脑子里应该立马想到键值对数据库。我一开始以为这就是 Redis,其实这并不是,这仅仅是 Redis 的其中一个模块而已。对于一个完整的 Redis,应该是由6大模块组成的:访问模块、索引模块、操作模块、存储模块、高可用集群模块、高可扩展集群模块。

访问模块
访问模块就是我们平时一定会接触的 Redis 的网络IO线程模型,如图:

Redis 是一个典型的 client-server 模型。首先,客户端先找 server-socket 建立连接,产生一个事件。IO多路复用器看到这么一个事件就把事件压入队列。文件事件分派器看到队列里有事件就把事件拿出来交给对应的事件处理器进行处理。处理过程是事件处理器会建立一个与客户端 socket 对应的新 socket。只要客户端 socket 与这个新 socket 通信,比如说发起了一个请求,新 socket 就会产生一个事件,然后IO多路复用器就会看到这个事件......重复上面的步骤。
这就是 Redis 的访问模块。访问模块也就是我们说的网络IO单线程模型。我的理解就是如果我们想访问 Redis 里面的键值对数据库,底层第一步要做的就是先进入这个键值对数据库,进入的方式就是我上面说的网络IO单线程模型。
索引模块
OK!回到刚才,我刚刚不是说了通过访问模块,我们已经访问到了键值对数据库了吗?那你有没有想过,这个键值对数据库是长什么样子的,又或者说这些键值对在 Redis 中是怎么存放的,那个画面你想过吗?其实是用一张全局哈希表来存放所有键值对的。这个哈希表由多个哈希桶组成,每个哈希桶存放一个或多个键值对。key 很好理解,因为 key 存放的只是 String 类型,但是 value 就不好理解了,value 支持很多种数据类型(String、列表、哈希、set、zset)。这些数据类型中,除了 String 类型之外,其他的几种类型都是数据集合。不过我当时在学习的时候就想象不出这个画面,我就想,一个 value 能存这么多数据?在我的理解里,我只能理解 value 是 String 类型的这种情况(value 是 String 类型的话,value 是存一个数据的,这很符合我的印象)。后来,我看到了一篇文章,然后我恍然大悟,原来 key-value 键值对存放的并不是实际的值,而是指针,这些指针指向数据集合!就像这样:

如果键值对越来越多,越来越多的话,我们就采用 rehash,即哈希扩容。这里的哈希扩容是渐进式的,没错,就是你学过的那个渐进式哈希扩容,每次对哈希表进行一次插入或者删除操作,就转移一个桶的数据到新表中,就像这样:

操作模块
OK!通过上面的文字和图片,我们应该大致知道 Redis 这个键值对数据库里面大概长什么样了,接下来我们来看看操作模块。操作模块其实就是对键值对的一些操作,除了一些最基础的 put、get、delete 之外,根据 value 中数据类型的不同,会有不同的操作方法。比如说,假如这个键值对的 value 的数据类型是列表 List,那么针对这种数据类型就提供 push 进队和 pop 出队这些对应的操作,就这么简单。
存储模块
这是 Redis 中最核心的模块了,因为这里知识点最多,但是又不是最难,我花了好多时间去理解这个知识点,理解了之后,感觉有种高山看海,海浪真美的感觉。
存储模块,研究的就是 value 中的5种数据类型和底层的6种数据结构,就像这个图:

String ——(动态字符串)
String 这种数据类型真的是万金油,名字虽然叫 String,但是它还可以存文本,数据.....感觉啥都能存。String 类型的底层数据结构是动态字符串,动态字符串提供了丰富的 String 操作命令:增减、排序、查找、计数.....比如我之前实习的公司,它就用 String 来做计数器,用来记录用户的刷新次数,防止一个用户一直刷新。
List ——(双向链表、压缩链表)
List这种数据类型的底层是双向链表的话,我们其实可以用 Redis 来做一个轻量的消息队列,具体怎么实现,我之前好像写过一篇文章:能否把 Redis 当做消息队列来用呢?-CSDN博客
而如果 List 的底层用压缩列表来实现的话,就体现出 Redis 很快很省。因为压缩列表,压缩嘛,肯定省,而且数据被压缩成连续的,所以查找起来就很快。
Hash ——(压缩列表、哈希表)
Hash 这种数据类型的底层实现可以是压缩列表或者是哈希表。如果底层实现是哈希表的话,那么 Redis 就可以用于缓存,比如说缓存用户的基本信息。怎么缓存用户的基本信息?就是 key 是用户ID,value 是用户的基本信息。
Set ——(哈希表、整数数组)
Set 这种数据类型的特点就是无序且不重复。之所有有这种特点,就是因为它底层的数据结构。哈希表是散列的是吧,散列那肯定就无序啊,而哈希表我们都学过不允许存重复的元素,所以数据就不重复。即哈希表是无序不重复的,因此Set也是无序不重复的。如果你用 Redis 来做消息队列的话,那么这个 Set 可以帮助保持消息队列的幂等性(即消息不被重复消费)。假如你理解不了这个例子,那换一个更加简单的,你肯定可以理解的例子。有一个数组a[5]=[2,4,2,4,7,6],你用一下Set,直接变成了[2,4,7,6],这你能理解了吧!
ZSet —— (压缩列表、跳跃表)
ZSet 和 Set 很像,只不过比起 Set,ZSet 是有序的,就这点不同,其他的感觉大差不差。比如说a[5]=[2,4,2,4,7,6],你用一下 ZSet,直接变成了[2,4,6,7]。所以Redis可以用于排行榜。
其实 Zset 本身并没有什么好讲的,但是 ZSet 底层用跳跃表这种数据结构来实现,跳跃表就可以好好讲讲了。假如我们用跳跃表这种数据结构来支持 ZSet 这种数据类型,那么在对 ZSet 这个有序集合的插入删除查找都是非常快的。跳跃表的原理我口头说不清,我觉得还是展示图片比较实在。我这里不谈跳跃表的插入删除操作,就谈跳跃表的查找操作。

说实话,其实我也不是很理解,暂时有点乱。不过关键的一点就是:通过上一层的元素来确定目标元素所在的区间。
我感觉跳跃表的查找就好像搭地铁一样,快线+慢线互相搭配,从而最快达到目的地。
高可用集群模块
高可用集群模块其实就是主从复制+哨兵机制,还有 AOF 和 RDB 技术。事实上感觉面试的 AOF和 RDB 技术这两个问的多一点,而主从复制+哨兵机制问的并不算多,也有可能是主从复制+哨兵机制相对而言比较复杂吧。关于 Redis 实现高可用的思想和 kafka 消息队列很像,特别是主从复制+哨兵机制那一块,感觉一模一样哈哈哈。
高可扩展集群模块
这个模块也没什么好讲的,Redis 就是通过数据分片来实现高扩展的。这一块感觉面试也问的不多,所以我也仅仅是做了简单的了解,并没有深挖太多。
总结
以上就是我脑图中的 Redis 的6大模块。假如你想要对键值对进行操作,首先你需要通过访问模块(网络IO单线程模型),然后你才可以进入到 Redis 的内部。在 Redis 内部,键值对是怎么存放的呢?其实是通过全局哈希表来存放所有键值对的,我也配了图,这就是索引模块。知道了 Redis 里面长什么样了,就到了真正对键值对进行操作了,操作模块其实就是一些简单的操作( put、get、delete ),加上 value 中不同数据类型提供的一些不同的操作。最后是存储模块,存储模块研究的问题是 value 中的值是用什么结构进行存储的,我们研究了5种数据类型以及这5种数据类型背后的6种底层数据结构,我也配了图,顺便说了一下这5种数据类型的一些使用场景。
其实这篇文章还没写完,但是 CSDN 的文章评分机制是,如果写太长的话,文章评分会降低,然后影响推流,所以我只好拆开来写了。
相关文章:
Redis 全景图(1)--- 关于 Redis 的6大模块
这是我第一次尝试以长文的形式写一篇 Redis 的总结文章。这篇文章我想写很久了,只是一直碍于我对 Redis 的掌握没有那么的好,因此迟迟未动笔。这几天,我一直在看各种不同类型的 Redis 文章,通过阅读这些文章,引发了我对…...
Lambda表达式,Stream流
文章目录 Lambda表达式作用前提函数式接口特点 语法省略模式和匿名对象类的区别 Stream流思想作用三类方法获取方法单列集合(Collection[List,Set双列集合Map(不能直接获取)数组同一类型元素(Stream中的静态方法) 常见的中间方法终结方法收集方法 Optional类 Lambda表达式 作用…...
Apache Hive的基本使用语法(一)
一、数据库操作 创建数据库 create database if not exists myhive;查看数据库 use myhive; desc database myhive;创建数据库并指定hdfs存储 create database myhive2 location /myhive2;删除空数据库(如果有表会报错) drop database myhive;…...
Python爬虫详解:原理、常用库与实战案例
前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言引言:一、爬虫原理1. HTTP请求与响应过程2. 常用爬虫技术 二、P…...
搭建跨境电商电商独立站如何接入1688平台API接口|通过1688API接口采集商品通过链接搜索商品下单
接口设计|接口接入 对于mall项目中商品模块的接口设计,大家可以参考项目的Swagger接口文档,以Pms开头的接口就是商品模块对应的接口。 参数说明 通用参数说明 参数不要乱传,否则不管成功失败都会扣费url说明……d.cn/平台/API类型/ 平台&…...
【GlobalMapper精品教程】073:像素到点(Pixels-to-Points)从无人机图像轻松生成点云
文章目录 一、工具介绍二、生成点云三、生成正射四、生成3D模型五、注意事项一、工具介绍 Global Mapper v19引入的新的像素到点工具使用摄影测量原理,从重叠图像生成高密度点云、正射影像及三维模型。它使LiDAR模块成为已经功能很强大的的必备Global Mapper扩展功能。 打开…...
论文复现1:Mobilealoha
abstract:从人类演示中进行的模仿学习在机器人技术中表现出了令人印象深刻的表现。然而,大多数结果都集中在桌面操作上,缺乏一般有用任务所需的移动性和灵活性。在这项工作中,我们开发了一种用于模仿双手且需要全身控制的移动操纵任务的系统。我们首先推出 Mobile ALOHA,这…...
pycharm复习
目录 1.基础语法 2.判断语句 3.while循环 4.函数 5.数据容器 1.基础语法 1.字面量 2.注释: 单行注释# 多行注释" " " " " " 3.变量: 变量名 变量值 print:输出多个结果&#x…...
【SQLSERVER】批量导出所有作业或链接脚本
1.在Microsoft SQL Server Management Studio中选择–>视图(v)–>对象资源管理器详细信息(F7) 2.SSMS图形界面,左侧是“对象资源管理器”,右侧是“对象资源管理器详细信息”界面 3.左侧的“对象资源管理器”界面–>点击“SQLSserver代理”–…...
函数参数缺省和内联函数【C++】
文章目录 函数参数缺省函数参数缺省的条件和要求 内联函数内联函数的工作原理内联函数的定义方法内联函数的要求解决方法:直接在.h中定义内联函数的函数体 内联函数再Debug模式下默认是不展开的 函数参数缺省 顾名思义:可以少传一个/多个参数给函数&…...
javaWeb城市公交查询系统的设计与实现
一、选题背景 随着低碳生活的普及,人们更倾向于低碳环保的出行方式,完善公交系统无疑具有重要意义。公交是居民日常生活中最常使用的交通工具之一,伴随着我国经济繁荣和城市人口增长,出行工具的选择也变得越来越重要。政府在公共…...
企业案例:金蝶云星空对接旺店通·企业版
某知名化妆品企业,主要专注于化妆品,护肤品等研发,销售,生产于一体化的企业。企业的业务模式涉及比较广,有2B,2C和国内外电商领域。由于对内部业务流程的连贯性和数据的准确性比较关注。财务系统用的金蝶云星空&#x…...
wpsword求和操作教程
wpsword求和怎么操作: 1、首先,单纯的数据是无法求和的,所以我们必须要“插入”一个“表格” 2、接着将需要求和的数据填入到表格中。 3、填完后,进入“布局”选项卡。 4、然后打开其中的“公式” 5、在其中选择求和公式“SUM”并…...
Android 手机部署whisper 模型
Whisper 是什么? “Whisper” 是一个由OpenAI开发的开源深度学习模型,专门用于语音识别任务。这个模型能够将语音转换成文本,支持多种语言,并且在处理不同的口音、环境噪音以及跨语言的语音识别方面表现出色。Whisper模型的目标是提供一个高效、准确的工具,以支持自动字幕…...
通信术语:初学者入门指南(二)
1.SAR:Synthetic Aperture Radar合成孔径雷达,是一种雷达系统,通常用于地球或行星的遥感成像。相较于传统的实孔径雷达,SAR 通过在相对较长的时间内,对来自同一地点的多个雷达反射信号进行综合处理,实现了更…...
Java中使用MQTT客户端库实现TLS/SSL加密通信的示例
以下是一个完整的Java代码示例,展示了如何使用Eclipse Paho MQTT客户端库在Java中实现TLS/SSL加密的MQTT通信。在这个示例中,我们将创建一个简单的MQTT客户端,该客户端连接到支持TLS/SSL的MQTT代理,并发布和订阅消息。 首先&…...
【m122】webrtc的比较
uint16的比较IsNewerSequenceNumber 和 u32的比较LatestTimestamp G:\CDN\WEBRTC-DEV\libwebrtc_build\src\modules\include\module_common_types_public.h/** Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.** Use of this source code is governed …...
axios发送get请求但参数中有数组导致请求路径多出了“[]“的处理办法
一、情况 使用axios发送get请求携带了数组参数时,请求路径中就会多出[]字符,而在后端也会报错 二、解决办法 1、安装qs 当前项目的命令行中安装 npm install qs2、引入qs库(使用qs库来将参数对象转换为字符串) // 全局 import qs from qs Vue.proto…...
vue3的mars3d点击右键出现置顶、向下、向上等选项
效果图 下载插件 imengyu/vue3-context-menu npm i imengyu/vue3-context-menu在要使用的页面中引入一下代码 import "imengyu/vue3-context-menu/lib/vue3-context-menu.css"; import ContextMenu from "imengyu/vue3-context-menu";如果是使用在树的…...
MySQL进阶-----SQL提示与覆盖索引
目录 前言 一、SQL提示 1.数据准备 2. SQL的自我选择 3.SQL提示 二、覆盖索引 前言 MySQL进阶篇的索引部分基本上要结束了,这里就剩下SQL提示、覆盖索引、前缀索引以及单例联合索引的内容。那本期的话我们就先讲解SQL提示和覆盖索引先,剩下的内容就…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
