Redis——五种数据类型

news2025/4/18 23:40:33

目录

前言

1.String

1.1RAW编码

1.2EMBSTR编码

1.3 INT编码

 2.List

3.Set

3.1 InSet编码转化成Dict编码

4.ZSet

4.1结合SkipList和HT实现

 4.2使用ZipList实现

4.3编码转换 

4.4 ZipList排序功能

5.Hash

5.1Hash底层存储结构

6.Redis数据结构和数据类型关系图 


前言

 Redis 中的每种数据类型都由特定的数据结构来实现,数据结构为数据类型提供了底层的存储和操作机制。

不同的数据类型具有不同的特性和应用场景,数据结构的选择和设计是为了更好地满足这些特性

数据结构是实现数据类型的基础,它们共同构成了 Redis 强大的功能体系,使得 Redis 能够在不同的应用场景中,根据数据的特点和操作需求,选择合适的数据类型和对应的数据结构来高效地处理和管理数据。

1.String

String是Redis中最常见的数据存储类型:

其基本编码方式是RAW,基于简单动态字符串(SDS)实现,存储上限为512mb。

查看编码:object encoding key

1.1RAW编码

ptr指针指向SDS,RedisObject和SDS是两个独立空间所以会有寻址过程通过ptr指针找到SDS。所以会有两次申请内存空间,释放内存也会有两次内存释放,效率比较低。

1.2EMBSTR编码

如果存储的SDS长度小于44字节,EMBSTR编码,此时object head与SDS是一段连续空间。申请内存时只需要调用一次内存分配函数,效率更高。

好处:减少内存碎片

Redis 通常按页分配内存,使用 jemalloc 等内存分配器,它会分配 8、16、32、64 等字节的内存块。对于小于 44 字节的字符串,采用 embstr 编码可以将其存储在一个连续的 64 字节内存块中,减少了内存碎片的产生

如果字符串较长,超过 44 字节,为其单独分配内存空间(转为 raw 编码),采用常规的 robj 和SDS分离方案性能下降,产生内存碎片

1.3 INT编码

如果存储的字符审是整数值,并且大小在LONG_MAX范围内,INT编码,直接将数据保存在RedisObject的ptr指针位置(刚好8字节),不再需要SDS了。


 2.List

Redis的List结构类似双端链表,可以从首尾操作列表中的元素

选择何种数据结构呢?

  1. LinkList:普通链表,可以从双端访问,链表每个节点都是独立的内存,节点与节点之间的访问通过指针,指针比较占用内存,内存碎片较多。
  2. ZipList:压缩列表,可以从双端访问,内存占用较低,存储上限低。如果一次性存储大量内存需要申请大量内存空间比较困难。
  3. QuickList:LinkedList+ZipList,可以双端访问,内存占用较低,包含多个ZipList,存储上限高。

在3.2版本之前,Redis采用ZipList来实现List,当元素数量小于512并且元素大小小于64字节时采用ZipList编码,超过则采用LinkedList编码。


在3.2版本之后,redis统一采用QuickList来实现List。Redis 可以通过list-max-ziplist-size参数来控制每个 ZipList 节点的大小,通过list-compress-depth参数来控制 QuickList 的压缩深度,即链表两端不压缩的节点数量,以此来平衡内存使用和操作性能。

插入元素底层源码

整体内存结构


3.Set

Set是Redis中的单列集合,满足下列特点:

  • 不保证有序性
  • 保证元素唯一(可以判断元素是否存在)
  • 求交集,并集,差集

不管是插入元素还是求交集等等这些操作都需要判断元素是否存在,这样就需要选择对元素查询效率较高的数据结构

  • 为了查询效率和唯一性,set采用HT编码(Dict)Dict中的key用来存储元素,value统一为null
  • 当存储的所有数据都是整数,并且元素数量不超过set-max-intset-entset会采用IntSet编码,以节省内存。

判断用哪种数据结构底层源码

创建IntSet数据结构底层源码

创建Dict数据结构底层源码

整体执行源码

3.1 InSet编码转化成Dict编码

当元素数量超过set-max-intset-entries或者存储元素不是数字了时会自动转换成Dict编码

执行结构图:

当插入一个元素为m1字符串时会升级为Dict编码,创建Dict数据结构

RedisObject指针ptr指向Dict,encoding编码改为Dict


4.ZSet

ZSet也就是SortedSet,其中每个元素都需要指定一个score值和member值:

可以根据score值排序

member必须唯一

可以根据member查询分数

因此,ZSet底层数据结构必须满足键值存储键必须唯一可排序这几个需求。

4.1结合SkipList和HT实现

  • SkipList:可以排序,并且可以同时存储score和ele值(member) | 满足键值存储和可排序
  • HT(Dict):可以键值存储,并且可以根据key找value | 满足高效查询键值唯一

所以ZSet底层是使用这两种数据结构来实现的dict用于快速查找SkipList用于键值存储和排序

底层源码:

内存图:

 4.2使用ZipList实现

使用上述那种方式这样带来的坏处就是ZSet非常占用内存空间,使用两种数据结构,存储两份。

当元素数量不多时,HT和SkipList的优势不明显,而且更耗内存。因此Zset还会采用ZipList不过需要同时满足两个条件:

  • 元素数量小于zset_max_ziplist_entries,默认值128
  • 每个元素都小于zset_max_ziplist_value字节,默认值64

底层判断使用哪种数据结构如下:

4.3编码转换 

既然ZSet底层都是用来两种编码方式根据不同情况,那么肯定会出现编码转换,添加元素不满足一下两个条件就会触发编码转换。

  • 元素数量小于zset_max_ziplist_entries,默认值128
  • 每个元素都小于zset_max_ziplist_value字节,默认值64

底层执行源码:

4.4 ZipList排序功能

ZipList本身没有排序功能,而且没有键值对的概念,因此需要有zset通过编码实现:

  • ZipList是连续内存,因此score和element是紧换在一起的两个entry,element在前,score在后
  • score越小越接近队首,score越大越接近队尾,按照score值升序排列

底层结构图:

因为元素比较少ZipList内存中是连续存储的,所以查找的时候就去遍历,插入元素的时候按照大小顺序插入,这样就保证了排序。性能也不错。


5.Hash

Hash结构与Redis中的Zset非常类似:

  • 都是键值存储
  • 都需要根据键获取值
  • 键必须唯一

区别如下:

  • zset的键是member,值是score;hash的键和值都是任意值
  • zset要根据score排序;hash则无需排序

5.1Hash底层存储结构

  • Hash结构默认采用ZipList编码,用以节省内存。ZipList中相邻的两个entry分别保存field和value
  • 当数据量较大时,hash结HT编码,也就是Dict,触发条件有两个:

                ziplist中的元素数量超过了hash-max-ziplist-entries(默认512)
                ziplist中的任意entry大小超过了hash-max-ziplist-value(默认64字节)

转换流程:

触发条件达成转换编码

6.Redis数据结构和数据类型关系图 

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

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

相关文章

Godot学习-创建简单动画

文章目录 1、准备工作Godot资源 2、创建项目3、创建结点4、创建动画1、创建动画2、添加轨道3、创建关键帧3.1 第一个关键帧3.2 第二个关键帧 5、加载后自动播放6、动画循环7、轨道设置1、轨道更新模式2、轨迹插值3、其他属性的关键帧4、编辑关键帧5、使用 RESET 轨道6、洋葱皮 …

论文阅读VACE: All-in-One Video Creation and Editing

code:https://github.com/ali-vilab/VACE 核心 单个模型同时处理多种视频生成和视频编辑任务通过VCU(视频条件单元)进行实现 方法 视频任务 所有的视频相关任务可以分为4类 文本生视频 参考图片生视频 视频生视频 视频mask生视频 VCU …

JavaSE学习(前端初体验)

文章目录 前言一、准备环境二、创建站点(创建一个文件夹)三、将站点部署到编写器中四、VScode实用小设置五、案例展示 前言 首先了解前端三件套:HTML、CSS、JS HTML:超文本标记语言、框架层、描述数据的; CSS&#xf…

前端渲染pdf文件解决方案

一、前言 在当今数字化信息传播的时代,PDF文档作为一种常见的文件格式扮演着重要的角色。对于前端开发者而言,实现在网页上渲染和展示PDF文件是一项常见但也具有挑战性的任务。幸运的是,现在有一个强大的工具——react-pdf-viewer&#xff0c…

Kubernetes(K8S)内部功能总结

Kubernetes(K8S)是云技术的最核心的部分,也是构建是云原生的基石 K8S K8S,是Kubernetes的缩写,是Google开发的容器编排平台,现在由云原生计算基金会(CNCF)进行维护。 K8S&#xff…

【计算机网络】3数据链路层①

这篇笔记专门讲数据链路层的功能。 2.功能 数据链路层的主要任务是让帧在一段链路上或一个网络中传输。 2.1.封装成帧(组帧) 解决的问题:①帧定界②帧同步③透明传输 实现组帧的方法通常有以下种。 2.1.1.字符计数法 原理:在每个帧开头,用一个定长计数字段来记录该…

Nginx底层架构(非常清晰)

目录 前言: 场景带入: HTTP服务器是什么? 反向代理是什么? 模块化网关能力: 1.配置能力: 2.单线程: 3.多worker进程 4.共享内存: 5.proxy cache 6.master进程 最后&…

Docker 设置镜像源后仍无法拉取镜像问题排查

#记录工作 Windows系统 在使用 Docker 的过程中,许多用户会碰到设置了国内镜像源后,依旧无法拉取镜像的情况。接下来,记录了操作要点以及问题排查方法,帮助我们顺利解决这类问题。 Microsoft Windows [Version 10.0.27823.1000…

Edge 浏览器推出 Copilot Vision:免费实时解析屏幕内容;Aqua Voice:极速 AI 语音输入工具丨日报

开发者朋友们大家好 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 观点 」、「有看…

async-profiler火焰图找出耗CPU方法

事情起于开发应用对依赖的三方包(apache等等)进行了升级后(主要是升级spring),CPU的使用率较原来大幅提升,几个应用提升50%-100%。 查找半天,对比每次版本的cpu火焰图,看不出有什么…

@Autowird 注解与存在多个相同类型对象的解方案

现有一个 Student 类,里面有两个属性,分别为 name 和 id;有一个 StuService 类,里面有两个方法,返回值均为类型为 Student 的对象;还有一个 StuController 类,里面有一个 Student 类型的属性&am…

WordPiece 详解与示例

WordPiece详解 1. 定义与背景 WordPiece 是一种子词分词算法,由谷歌于2012年提出,最初用于语音搜索系统,后广泛应用于机器翻译和BERT等预训练模型。其核心思想是将单词拆分为更小的子词单元(如词根、前缀/后缀),从而解决传统分词方法面临的词汇表过大和未知词(OOV)处…

PVE+CEPH+HA部署搭建测试

一、基本概念介绍 Proxmox VE ‌Proxmox Virtual Environment (Proxmox VE)‌ 是一款开源的虚拟化管理平台,基于 Debian Linux 开发,支持虚拟机和容器的混合部署。它提供基于 Web 的集中管理界面,简化了计算、存储和网络资源的配置与监控。P…

ROS ROS2 机器人深度相机激光雷达多传感器标定工具箱

系列文章目录 目录 系列文章目录 前言 三、标定目标 3.1 使用自定义标定目标 四、数据处理 4.1 相机数据中的标定目标检测 4.2 激光雷达数据中的标定目标检测 输入过滤器: 正常估算: 区域增长: 尺寸过滤器: RANSAC&a…

android rtsp 拉流h264 h265,解码nv12转码nv21耗时卡顿问题及ffmpeg优化

一、 背景介绍及问题概述 项目需求需要在rk3568开发板上面,通过rtsp协议拉流的形式获取摄像头预览,然后进行人脸识别 姿态识别等后续其它操作。由于rtsp协议一般使用h.264 h265视频编码格式(也叫 AVC 和 HEVC)是不能直接用于后续处…

熊海cms代码审计

目录 sql注入 1. admin/files/login.php 2. admin/files/columnlist.php 3. admin/files/editcolumn.php 4. admin/files/editlink.php 5. admin/files/editsoft.php 6. admin/files/editwz.php 7. admin/files/linklist.php 8. files/software.php 9. files…

DeepSeek 与开源:肥沃土壤孕育 AI 硕果

当 DeepSeek 以低成本推理、多模态能力惊艳全球时,人们惊叹于国产AI技术的「爆发力」,却鲜少有人追问:这份爆发力的根基何在? 答案,藏在中国开源生态二十余年的积淀中。 从倪光南院士呼吁「以开源打破垄断」&#xf…

Maven中clean、compil等操作介绍和Pom.xml中各个标签介绍

文章目录 前言Maven常用命令1.clean2.vaildate3.compile4.test5.package6.verify7.install8.site9.deploy pom.xml标签详解格式<?xml version"1.0" encoding"UTF-8"?>(xml版本和编码)modelVersion&#xff08;xml版本&#xff09;groupId&#xff…

力扣刷题-热题100题-第35题(c++、python)

146. LRU 缓存 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/lru-cache/?envTypestudy-plan-v2&envIdtop-100-liked 双向链表哈希表 内置函数 对于c有list可以充当双向链表&#xff0c;unordered_map充当哈希表&#xff1b;python有OrderedDic…

Nautilus 正式发布:为 Sui 带来可验证的链下隐私计算

作为 Sui 安全工具包中的强大新成员&#xff0c;Nautilus 现已上线 Sui 测试网。它专为 Web3 开发者打造&#xff0c;支持保密且可验证的链下计算。Nautilus 应用运行于开发者自主管理的可信执行环境&#xff08;Trusted Execution Environment&#xff0c;TEE&#xff09;中&a…