Redis面试必问:Redis为什么快?Redis五大基本数据类型
请记住胡广一句话,所有的中间件所有的框架都是建立在基础之上,数据结构,计算机网络,计算机原理大伙一定得看透!!~
1. Redis快的秘密
相信大部分Redis初学者都会忽略掉一个重要的知识点,Redis其实是单线程模型。我们按直觉来看应该是多线程比单线程更快、处理能力更强才对,比如单线程一次只可以做一件事情,而多线程却可以同时做十件事情。
但Redis却可以做到每秒万级别的处理能力,主要是基于以下原因:
(1)Redis是基于内存操作的,Redis所有的数据库状态都保存在内存中。而内存的响应时长是非常快速的,大约在100纳秒。大家可以对比下其他服务器磁盘,固态硬盘(SSD)、机械硬盘(HDD)响应时长大约几十微秒,很明显远远没有基于内存的响应时长快速。
(2)Redis采用I/O多路复用技术,这种I/O模型是非阻塞I/O,应用程序在等待I/O操作完成的过程中不需要阻塞。
(3)最后一点也是我开头提到的,Redis采用了单线程模型。单线程模型避免了多线程产生的线程切换和锁竞争带来的资源消耗,这两种消耗对性能影响是很大的。另外一点是单线程相比多线程来说实现更简单高效,如果引入多线程设计相信Redis实现起来会更加复杂不易优化。
2. Redis数据类型
2.1 Redis五大基本数据类型
Redis基本数据类型一共有五种,这也是面试官重点考查的基础,大家要重点关注下。
(1)字符串。
字符串是Redis最基础,也是业务开发中最常见的一种数据类型。在业务上一般使用MySQL作为实际存储层,而Redis字符串作为缓冲层对象。
127.0.0.1:6379> set name JavaGetOffer
OK
127.0.0.1:6379> get name
"JavaGetOffer"
(2)哈希。
哈希的键值本身是一个键值对结构,类似于key = {{field, value}, {field, value}}。
我们可以使用hset命令设置哈希键值,而hget命令可以获取哈希对象中某个field的值。
127.0.0.1:6379> hset msg name JavaGetOffer
(integer) 1
127.0.0.1:6379> hset msg avator 思考的陈
(integer) 1
127.0.0.1:6379> hget msg name
"JavaGetOffer"
127.0.0.1:6379> hget msg avator
"思考的陈"
(3)列表。
Redis的列表是一个有序列表,但大家注意一点,此处所说的有序不是按数据大小排序的有序,而是按插入顺序的有序。另外一点特殊之处是我们可以往列表的左右两边添加元素。
# 从右边添加
127.0.0.1:6379> rpush number 1 2 3
(integer) 3
# 从左边添加
127.0.0.1:6379> lpush number 4 5 6
(integer) 6
127.0.0.1:6379> lrange number 0 5
1) "6"
2) "5"
3) "4"
4) "1"
5) "2"
6) "3"
(4)集合。
集合类型和列表不同之处在于它是无序的,同时也不支持保存重复的元素。
另外两个集合之间可以获得交集、并集、差集。利用这一点,如果在业务上要求得两个用户相同的兴趣标签,可以使用Redis集合存储用户兴趣标签,再使用交集命令来查询。
127.0.0.1:6379> sadd user:1:like game bask run
(integer) 3
127.0.0.1:6379> sadd user:2:like game basketball fitness
(integer) 3
# 求交集
127.0.0.1:6379> sinter user:1:like user:2:like
1) "game"
(5)有序集合。
有序集合算是Redis中比较特殊的一种数据类型,有序集合里的每个元素都带有一个score属性,通过该score属性进行排序。如果我们往有序集合插入元素,此时它就不像列表对象一样是插入有序,而是根据score进行排序的。
127.0.0.1:6379> zadd 100run:ranking 13 mike
(integer) 1
127.0.0.1:6379> zadd 100run:ranking 12 jake
(integer) 1
127.0.0.1:6379> zadd 100run:ranking 16 tom
(integer) 1
127.0.0.1:6379> zrange 100run:ranking 0 2
1) "jake"
2) "mike"
3) "tom"
2.2 有序集合业务场景
有序集合典型的业务开发场景是实现一个排行榜,我们可以通过有序集合的score元素来作为排行榜排序的标准。
而排行榜的获取一般是分页获取,我们可以使用jedis客户端提供的zrevrangeWithScores方法来获得,返回的类型是一个Set<Tuple>,从Tuple对象中可以获得元素和score值,如代码所示。
try (Jedis jedis = jedisPool.getResource()) {String rankKey = "rankKey";Set<Tuple> rankTuple = jedis.zrevrangeWithScores(rankKey, index, index + pageSize - 1);List<UserRankBO> = rankTuple.stream().map(r -> UserRankBO.builder().uid(Integer.parseInt(r.getElement())).score(r.getScore()).build()).collect(Collectors.toList());}public Set<Tuple> zrevrangeWithScores(String key, long start, long stop) {this.checkIsInMultiOrPipeline();this.client.zrevrangeWithScores(key, start, stop);return this.getTupledSet();}
2.3 有序集合数据结构
有序集合有两种内部编码:ziplist和skiplist。ziplist编码是以压缩列表来实现,而在skiplist编码中是同时使用字典和跳跃表两种数据结构来实现的。
(1)字典。
字典里保存的是键值对结构,和上文提交的哈希对象不是同一个级别的产物,字典是Redis内部的数据结构,而哈希对象是提供给外部使用的。例如存储键的键空间、存储建过期时间的过期字典都是由字典来实现的。
字典的组成结构如下所示。可以看到ht数组有两个dictht哈希表,Redis的平常使用时只使用其中一个哈希表,而另一个是在迁移扩展哈希表rehash时使用。当迁移完成后,原先日常使用的旧哈希表会被清空,而新的哈希表变成日常使用的。
typedef struct dict {dictType *type;void *privdata;// 哈希表dictht ht[2];in trehashidx;
} dict;
(2)跳跃表。
跳跃表的底层结构类似于一个值 + 保存了指向其他节点的level数组,而这个level数组的作用就是用来加快访问其他节点的速度。跳跃表的查询效率是比较快的,可以和平衡二叉树相媲美,同时跳跃表相比平衡树的实现更加的简单。
跳跃表的组成结构如下所示。
typedef struct zskiplistNode {// level数组struct zskiplistLevel {// 前进指针struct zskiplistNode *forward;// 跨度unsigned int span;} level[];// 后退指针struct zskiplistNode *backward;// 分值double score;robj *obj;
} zskiplistNode;
2.4 为什么使用字典和跳跃表
同时使用字典和跳跃表的设计主要是考虑了性能因素,两者都有其效率最高的场景,要高效利用它们来提高Redis性能。
- 如果单纯使用字典,查询时的效率很高,可以达到高效的O(1)时间复杂度。但执行类似ZRANGE、ZRNK命令时,效率是比较低的。因为每次排序需要在内存上对字典进行排序一次,这消耗了额外的O(n)内存空间。
- 如果单纯使用跳跃表,虽然执行类似ZRANGE、ZRNK命令时的效率高,但查询性能又会从O(1)上升到了O(logN)。
所以Redis内部会对有序集合采用字典和跳跃表两种实现,当使用对应不同场景时,就采用对应的不同数据结构来高效操作有序集合。
3. 压缩列表
压缩列表顾名思义作用在于压缩,主要是Redis为了节约内存开发的一种数据结构。一共有三种数据类型使用到了压缩列表。
列表键里如果包含的都是类似小整数、短字符串类型的,会采用压缩列表的底层实现。
127.0.0.1:6379> rpush number 1 2 3
(integer) 3
127.0.0.1:6379> object encoding number
"ziplist"
哈希键如果只包含少量的键值对,同时键、值都是类似小整数、短字符串类型的,会采用压缩列表的底层实现。
127.0.0.1:6379> hset msg name JavaGetOffer
(integer) 1
127.0.0.1:6379> hset msg avator 思考的陈
(integer) 1
127.0.0.1:6379> object encoding msg
"ziplist"
有序集合当元素个数小于128个时,内部编码会转换为压缩列表ziplist。
127.0.0.1:6379> zadd 100run:ranking 13 mike 12 jake 16 tom
(integer) 3
127.0.0.1:6379> object encoding 100run:ranking
"ziplist"
胡广简单的总结下:
Redis之所以快,得益于内存存储、单线程架构、I/O多路复用、高效数据结构等优化。同时,Redis提供了丰富的五种基本数据类型(字符串、哈希、列表、集合、有序集合),可以灵活地解决多种业务场景下的需求,广泛应用于缓存、消息队列、排行榜、计数器等场景。意识到数据结构以及计算机原理,计算机网络的重要性了吧,还不快赶紧去学??😄😄😄

你好,我是胡广。 致力于为帮助兄弟们的学习方式、面试困难、入职经验少走弯路而写博客 🌹🌹🌹 坚持每天两篇高质量文章输出,加油!!!🤩
如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注 吧 我会尽力带来有趣的内容 。
😎感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以 给我留言咨询,希望帮助更多的人
更多专栏:
📊 Java设计模式宝典:从入门到精通(持续更新)📝 Java基础知识:GoGoGo(持续更新)
⚽ Java面试宝典:从入门到精通(持续更新)
🌟 程序员的那些事~(乐一乐)
🤩 Redis知识、及面试(持续更新)
🚀 Kafka知识文章专栏(持续更新)
🎨 Nginx知识讲解专栏(持续更新)
📡 未完待续。。。
🎯 未完待续。。。
🔍 未完待续。。。
感谢订阅专栏 三连文章
相关文章:
Redis面试必问:Redis为什么快?Redis五大基本数据类型
请记住胡广一句话,所有的中间件所有的框架都是建立在基础之上,数据结构,计算机网络,计算机原理大伙一定得看透!!~ 1. Redis快的秘密 相信大部分Redis初学者都会忽略掉一个重要的知识点,Redis…...
InternVL2- dockerfile环境变量持久化使用`ENV`而不是`RUN export`来设置环境变量,以确保环境变量在容器运行时仍然可用
在Dockerfile中使用RUN export命令设置环境变量并不是一种持久化的方式。当你在Dockerfile中使用export命令时,它只会在当前构建阶段生效,并不会被持久化到生成的镜像中。这是因为export命令实际上是在shell环境中设置环境变量,而Docker构建过…...
Python(PyTorch和TensorFlow)图像分割卷积网络导图(生物医学)
🎯要点 语义分割图像三层分割椭圆图像脑肿瘤图像分割动物图像分割皮肤病变分割多模态医学图像多尺度特征生物医学肖像多类和医学分割通用图像分割模板腹部胰腺图像分割分类注意力网络病灶边界分割气胸图像分割 Python生物医学图像卷积网络 该网络由收缩路径和扩…...
DevOps实现CI/CD实战(七)- Jenkins集成k8s实现自动化CI
自动化CI操作 1. 安装gitlab plugin 工具 ##### 2. 配置流水线任务的构建触发器,复制URL:http://192.168.201.111:8080/project/pipeline 3. Gitlab配置Webhooks,将上面的url:http://192.168.201.111:8080/project/pipeline粘…...
从ES6到ES2023 带你深入了解什么是ES
从ES6到ES2023,我们深入探索ECMAScript(简称ES)的演变与发展,了解这一JavaScript标准背后的技术革新和进步。ECMAScript作为JavaScript的标准化版本,每年都在不断推出新版本,为开发者带来更加丰富和强大的功…...
openVX加速-常见问题:适用场景、AI加速、安装方式等
1. 哪些算法处理推荐使用 OpenVX OpenVX 是非常适合图像处理和计算机视觉任务的框架,特别是在需要高性能和硬件加速的场景下。如果你的前处理和后处理涉及到图像滤波、边缘检测、颜色转换等操作,使用 OpenVX 可以带来性能提升。 OpenVX 更适合处理以下…...
国产芯片LT8711HE:TYPE-C/DP1.2转HDMI2.0转换器,4k60Hz高分辨率
以下为LT8711HE芯片的简单介绍,如有介绍不尽之处,请指出 LT8711HE是一个高性能的Type-C/DP1.2到HDMI2.0转换器,用于连接USB Type-C源或DP1.2源到HDMI2.0接收器。 LT8711HE集成了一个DP1.2兼容的接收器和一个HDMI2.0兼容的发射器。另外&…...
论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey
Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs&…...
Java+Swing用户信息管理系统
JavaSwing用户信息管理系统 一、系统介绍二、功能展示1.管理员登陆2.用户信息查询3.用户信息添加4.用户信息修改5.用户信息删除 三、系统实现1.UserDao .java 四、其它1.其他系统实现 一、系统介绍 该系统实现了管理员系统登陆、用户信息查询、用户信息添加、用户信息修改、用…...
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值特殊矩阵的压缩存储
文章目录 栈的应用1.栈的括号匹配代码实战:问题分析:2.栈的表达式求值2.1 中缀、后缀、前缀表达式2.2 中缀表达式改写为后缀表达式(手算)2.3 后缀表达式的计算(手算)2.4 中缀表达式转前缀表达式(手算)和计算前缀表达式2.5后缀表达式的计算(机算)2.6 中缀表达式转后缀…...
C# 关于多线程同步不同实现方式
栏目总目录 AutoResetEvent class MainClass {// the array of consumer threadsprivate static List<Thread> consumers new List<Thread> ();// the task queueprivate static Queue<Action> tasks new Queue<Action>();// the synchronisation o…...
【人工智能学习笔记】4_2 深度学习基础之多层感知机
感知机概述 感知机是人工智能最早的模型,是一种有监督的算法,本质上是一个二分类问题,是神经网络和支持向量机的基础缺点:感知机智能解决单纯的线性问题 感知机的过程 多层感知机的层级结构 多层感知机的层级结构主要包括输入层、隐藏层和输出层、可以用于拟合非线性函数。…...
WPS2019如何打出各种横线
WPS2019如何打出各种横线 测试于WPS2019...
Vue获取后端重定向拼接的参数
前言 比如我们要重定向这样一个连接: http://192.168.2.189:8081?nameadmin springboot重定向: Vue获取: getParam(param) {var reg new RegExp("(^|&)" param "([^&]*)(&|$)");var r location.searc…...
vscode spring boot项目编辑yaml不自动提示补全如何解决
文章目录 properties能够自动弹出提示但是YAML文件就不会自动弹出提示ctrl空格不出提示的解决办法 properties能够自动弹出提示 但是YAML文件就不会自动弹出提示 只是不会自动弹出来而已,按ctrl空格即可解决 ctrl空格不出提示的解决办法 如果按ctrl空格没有用 …...
算法练习题19——leetcode141环形链表
题目描述 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&a…...
基于人类反馈的强化学习概述
文章目录 RLHF 概述人类反馈数据的收集由于对齐标准难以通过形式化的优化目标进行建模,因此研究人员提出了基于人类反馈的强化学习(Reinforcement Learning from Human Feedback, RLHF),引入人类反馈对大语言模型的行为进行指导。我们将首先介绍基于人类反馈的强化学习的整…...
【SIT1463Q】带振铃抑制功能的CAN收发器,替代TJA1463
【SIT1463Q】带振铃抑制功能的CAN收发器,替代TJA1463 SIT1463Q核心亮点: 满足ISO11898-2:2016高速CAN规范的物理层要求和CiA601-4:2019 SIC规范要求。 支持高达8Mbps的数据速率。 更稳定的位时序,比特对称性增强,降低…...
CCF刷题计划——坐标变换(其二)(前缀和)
坐标变换(其二) 首先我按照一般的逻辑写出来,居然超时了??? 之后想了想,还是觉得大有可为的,对拉伸前缀积,对旋转前缀和成功解决问题。 80分:超时 #inclu…...
游戏开发简述
《黑神话:悟空》爆红后,游戏开发一时成为热点。作为个人或小公司,能否进入游戏开发领域。从纯技术角度而言,并不是可望不可即: 另:学会了,哪怕自己干不成,招游戏开发的岗位也不少&am…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

