Redis 全景图(1)--- 关于 Redis 的6大模块

news/2024/7/26 11:17:29/文章来源:https://blog.csdn.net/qq_54432917/article/details/137157665

这是我第一次尝试以长文的形式写一篇 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 的文章评分机制是,如果写太长的话,文章评分会降低,然后影响推流,所以我只好拆开来写了。

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

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

相关文章

zabbix主动发现,注册及分布式监控

主动发现 结果 主动注册 结果 分布式监控 服务机:132 代理机:133 客户端:135 代理机 数据库赋权: 代理机配置 网页上配置代理 客户端配置 网页上配置主机 重启代理机服务 网页效果

算法学习——LeetCode力扣图论篇1(797. 所有可能的路径、200. 岛屿数量、695. 岛屿的最大面积)

算法学习——LeetCode力扣图论篇1 797. 所有可能的路径 797. 所有可能的路径 - 力扣(LeetCode) 描述 给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特…

使用Bitmaps位图实现Redis签到

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Redis提供了Bitmaps这个“数据类型”可以实现对位的操作: (1) Bitmaps…

springcloud基本使用四(Feign远程调用)

springcloud创建两个子项目order-server和user-server具体数据信息请查看springcloud前三章 order-server向user-server远程调用数据 order-server引入依赖&#xff1a; <dependency><groupId>org.springframework.cloud</groupId><artifactId>sprin…

pygwalker+streamlit python看板库使用体验

算作前言 在 B 站看到 pygwalker 的介绍&#xff0c;很感兴趣。 是一个类似于简化版的 tableau 工具。 原版 docs PyGWalker 文档 – Kanaries 搭建看板 直接结合 streamlit 使用&#xff0c;streamlit 真的神器。 import pygwalker as pyg import pandas as pd import str…

HarmonyOS 应用开发之启动/停止本地PageAbility

启动本地PageAbility PageAbility相关的能力通过featureAbility提供&#xff0c;启动本地Ability通过featureAbility中的startAbility接口实现。 表1 featureAbility接口说明 接口名接口描述startAbility(parameter: StartAbilityParameter)启动Ability。startAbilityForRes…

Object类的方法-(重点)equals()

根据JDK源代码及Object类的API文档&#xff0c;Object类当中包含的方法有11个。这里我们主要关注其中的6个&#xff1a; 1、(重点)equals() &#xff1a; 基本类型比较值:只要两个变量的值相等&#xff0c;即为true。 int a5; if(a6){…} 引用类型比较引用(是否指向同一个对象…

【Flume】尚硅谷学习笔记

实时监控目录下多个新文件 本案例是将虚拟机本地文件进行实时监控&#xff0c;并将上传的数据实时上传到HDFS中。 TAILDIR SOURCE【实现多目录监控、断点续传】 监视指定的文件&#xff0c;一旦检测到附加到每个文件的新行&#xff0c;就几乎实时地跟踪它们。如果正在写入新行…

空间数据结构(四叉树,八叉树,BVH树,BSP树,K-d树)

下文参考&#xff1a;https://www.cnblogs.com/KillerAery/p/10878367.html 游戏编程知识课程 - 四分树(quadtree)_哔哩哔哩_bilibili 利用空间数据结构可以加速计算&#xff0c;是重要的优化思想。空间数据结构常用于场景管理&#xff0c;渲染&#xff0c;物理&#xff0c;游…

CSS使用clip-path实现元素动画

前言&#xff1a; 在日常开发当中&#xff0c;如果想要开发多边形&#xff0c;一般都需要多个盒子或者伪元素的帮助&#xff0c;有没有一直办法能只使用一个盒子实现呢&#xff1f; 有的&#xff1a;css裁剪 目录 前言&#xff1a; clip-path到底是什么&#xff1f; clip-pa…

基于springboot+vue+Mysql的企业客户信息反馈平台

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

Windows 电脑麦克风 自动启用/禁用 小玩具!

WinMicrophone Windows 系统的 麦克风设备&#xff08;启用/禁用&#xff09;切换驱动&#xff01;它是小巧且快速的&#xff0c;它能够自动的检测并切换麦克风的情况。 您可以在软件包仓库中找到发布版本的exe包&#xff0c;无需安装&#xff01;其能够大大增大您在Windows中…

6.3物联网RK3399项目开发实录-驱动开发之I2C 使用(wulianjishu666)

物联网开发源码案例集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1kfPDpYZpm_G0GBLAup3KTQ?pwdvgvv I2C 使用 简介 AIO-3399J 开发板上有 9 个片上 I2C 控制器&#xff0c;各个 I2C 的使用情况如下表&#xff1a; 本文主要描述如何在该开发板上配置 I2C。 配置…

WebCopilot:一款功能强大的子域名枚举和安全漏洞扫描工具

关于WebCopilot WebCopilot是一款功能强大的子域名枚举和安全漏洞扫描工具&#xff0c;该工具能够枚举目标域名下的子域名&#xff0c;并使用不同的开源工具检测目标存在的安全漏洞。 工具运行机制 WebCopilot首先会使用assetsfinder、submaster、subfinder、accumt、finddom…

大数据学习第十二天(hadoop概念)

1、服务器之间数据文件传递 1&#xff09;服务器之间传递数据&#xff0c;依赖ssh协议 2&#xff09;http协议是web网站之间的通讯协议&#xff0c;用户可已通过http网址访问到对应网站数据 3&#xff09;ssh协议是服务器之间&#xff0c;或windos和服务器之间传递的数据的协议…

C语言第三十九弹---预处理(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 预处理 1、预定义符号 2、#define定义常量 3、#define定义宏 4、带有副作用的宏参数 5、宏替换的规则 6、宏和函数的对比 总结 在C语言中&#xff0c;预处…

阿里云2核4G云服务器支持多少人同时在线?并发数计算?

阿里云2核4G服务器多少钱一年&#xff1f;2核4G配置1个月多少钱&#xff1f;2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

蓝奏云直链获取在线解析网站源码

源码简介 蓝奏云直链获取在线解析网站源码 蓝奏云链接解析 本地API接口 支持有无密码和短期直链和永久直链&#xff0c;同时还可以显示文件名和大小。 这个解析器无需数据库即可搭建&#xff0c;API接口已经本地化&#xff0c;非常简单易用。 安装环境 php5.6 搭建教程 …

在编程中使用中文到底该不该??

看到知乎上有个热门问题&#xff0c;为什么很多人反对中文在编程中的使用&#xff1f; 这个问题有几百万的浏览热度&#xff0c;其中排名第一的回答非常简洁&#xff0c;我深以为然&#xff1a; 在国内做开发&#xff0c;用中文写注释、写文档&#xff0c;是非常好的习惯&…

前端工程师————HTML5学习

HTML5基础 开发工具很多&#xff0c;其中Hbulider较好用&#xff0c;下载网址如下&#xff1a; DCloud - HBuilder、HBuilderX、uni-app、uniapp、5、5plus、mui、wap2app、流应用、HTML5、小程序开发、跨平台App、多端框架 html表示整个页面 head表示搜素框 body表示内容 ti…