【Redis-03】Redis数据结构与对象原理 -下篇

news2025/3/1 21:19:11

 承接上篇【Redis-02】Redis数据结构与对象原理 -上篇

8. type-字符串string

在这里插入图片描述

8.1 字符串的三种encoding编码(int + embstr + raw)

  • 如果保存的是整型,并且可以用long类型标识(-9223372036854775808到9223372036854775807),encoding取值为 int
  • 如果是浮点数 + 整型(long类型无法表达) + 字符串,且长度 ≤ 44个字节,encoding 取值为 embstr
  • 如果是浮点数 + 整型(long类型无法表达) + 字符串,且长度 > 44个字节,encoding 取值为 raw
    想知道为什么是44个字节吗?点击这里可以查看https://blog.csdn.net/u013099854/article/details/115399466
    在这里插入图片描述
    在这里插入图片描述

8.1.2 embstr 和 raw两种编码

 这两种编码内部封装的都是sds,站在使用者的角度而言,没什么区别;在底层内存分配及部分操作时,还是有一些不同的,主要体现在以下几点:

  1. embstr是用于保存短字符串的优化编码方式,且embstr编码的字符串对象是只读的,对此编码进行任何的写操作,都会导致字符串变为raw的编码方式;raw是用于保存长字符串的编码方式。
  2. embstr在内存分配和内存释放的时候,只需调用一次对应的函数;而raw需要调用两次内存分配和释放的函数来完成对应的过程;
  3. embstr编码的字符串对象所有的数据都是保存在一块连续的内存里,而raw不一定。

 embstr内存连续,如下图:
在这里插入图片描述
 raw内存不连续,如下图:
在这里插入图片描述

8.1.3 编码转换

  • 整数型经过某些操作,比如append、setrange; encoding: int -> raw
  • 整数型涉及到浮点数的操作,比如incrbyfloat; encoding:int -> embstr或raw
  • 短字符串经过某些写的操作,比如append、setrange; encoding : embstr -> raw
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

9 type-集合set

在这里插入图片描述
 redis中,set的类型是借助于intset和dict来实现的,与其他结构一样,在某些条件下,set的编码类型会发生变化。我们来看下,set在哪些情况下使用intset,哪些情况下使用dict。

9.1 类型转换

  • 我们创建一个set,写入 1、 3、 5、 7 这样的整数值时,set的encoding是intset,但是如果我们写入非整数 a,就会变成 dict 类型。
  • 我们创建一个set,写入 1、 3、 5、 7 这样的整数值时,set的encoding是intset,但是如果我们写入的整数 >264-1,就会变成 dict 类型。
  • 当set的元素超过 512 个时,编码类型会从 intset转为 dict,这个值也是在redis.conf的配置文件中定义的。
    在这里插入图片描述
     看下面的几个例子:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

9.2 两种类型比较

 我们看下set在不同编码下的数据结构,下图分别是intset 和 dict的实现:
在这里插入图片描述
在这里插入图片描述
 在set较小的时候,使用intset可以节省内存,因为dict要维护两个哈希表,链表指针及其他大量元数据,而intset是一整块连续的内存。但是dict的平均查找效率是高于intset的,dict可以支持O(1)的时间复杂度,而intset是有序的整数集合,可以做二分查找,时间复杂度是O(log n)。

 这里需要说明一点的是,如果set使用dict作为底层实现,key是set的元素值,而 value = null。

10 type-哈希hash

在这里插入图片描述
 hash是我们在redis中存储对象比较理想的数据结构,每个对象的属性正好可以对应hash的每个field。hash的底层数据结构就是基于压缩列表和字典这两种类型实现的。

10.1 encoding的编码转换

 当hash对象可以同时满足下面2个条件时,使用的是ziplist,否则就是dict。

  • 哈希对象保存的所有键值对的键和值字符串长度都 ≤ 64个字节;
  • 哈希对象保存的键值对的数量 ≤ 512个;
    在这里插入图片描述

10.2 举例说明

  • 下面这个案例,aa是64个字节,bb是65个字节

在这里插入图片描述

  • 下面这个案例,numbers1是512个键值对,numbers2是513个键值对
    在这里插入图片描述

11 type-有序列表 sorted set

在这里插入图片描述

  Redis中的sorted set,其实是在ziplist,skiplist和dict的基础上共同构建而来的,在不同的场景下,使用的数据结构是不一样的。决定使用哪种数据结构,涉及到redis.conf中的两个配置参数,分别是 zset-max-ziplist-entries 和 zset-max-ziplist-value。

在这里插入图片描述

  • 如果有序集合中的元素数量≤128(对应的ziplist中entry的个数就是128*2=256个),并且所有元素的长度都≤64个字节的时候,就会使用ziplist作为底层的结构实现。
  • 如果有序集合中的元素数量超过128个,或者某个元素成员对象的长度超过64个字节的时候,就会使用zset的数据结构,而zset的数据结构其实就是由1个dict + 1个 zskiplist结构组成的。

在这里插入图片描述
在这里插入图片描述

11.1 使用 ziplist 的数据结构

 前面我们了解的ziplist是占用了一大块连续的内存,它的数据项都是相邻的。在数据项较少的时候,我们向有序集合中插入一条数据,ziplist上面就会插入两个entry节点,成员对象ele在前,分数score在后面,而且这些元素都是按照分值从小到大进行排序保存的。它的优势就是节省内存开销,支持从前往后或者从后往前的顺序查找。

 如果我们执行了这样一条命令,向学生有序集合中插入分数和姓名,他的类型就是ziplist:

在这里插入图片描述

 那么数据结构就是这样的
在这里插入图片描述

11.2 使用 dict + zskiplist 的数据结构

 在数据量比较多的时候,有序集合使用了 dict + zskiplist两种结构共同来实现。dict用于保存数据与分值之间的对应关系,key=成员对象,value=分值,这也是为什么数据值如果相同,后者会覆盖前者的原因。 而zskiplist用于使用分数来查找数据,也支持范围内的查找。虽然zset同时使用了字段和跳跃表,但是这两种数据结构都会通过指针来共享相同的元素和分值,所以不会产生重复的数据,也不会额外占用内存。

 如果我们执行了这样一条命令,向学生有序集合中插入分数和姓名,他的类型就是skiplist(zset):
在这里插入图片描述

11.3 编码的转换

 我现在分别写入128个元素和129个元素、长度为64和长度为65的元素,看一下他们的encoding的编码类型是什么。

在这里插入图片描述

在这里插入图片描述

 可以看到,上面两种情况的encoding编码值确实发生了变化。

 理论上,有序集合可以单独使用dict或者zskiplist来实现,但是为什么要使用两者结合呢,是因为无论单独使用哪一种,在性能上对比起同时使用两者时性能都会有所下降。下面我们看个例子:

在这里插入图片描述

 如果仅使用zskiplist,现在查找dd的排序:首先我们现在知道的是成员对象,而不是分值,所以就没有办法在O(log n)的时间复杂度下找到对应的节点,只能循环遍历,从头开始找,每循环一个对比一下 ele ?= dd,直到命中为止,时间复杂度就是O(n);

 而现在zset借助了dict,首先根据key=dd找到对应的value,这一步在哈希值冲突较小的前提下时间复杂度是O(1),而找到分值score后,借助于zskiplist的特性在O(log n)的时间复杂度下找到dd这个节点,然后再把沿途的跨度数值加起来,就是dd的排位。

在这里插入图片描述

12 type-列表list

在这里插入图片描述

12.1 编码类型

 redis中列表list就是借助于quicklist来实现的,而且只有这一种编码类型。
在这里插入图片描述

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

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

相关文章

Git:常用命令(二)

查看提交历史 1 git log 撤消操作 任何时候,你都有可能需要撤消刚才所做的某些操作。接下来,我们会介绍一些基本的撤消操作相关的命令。请注意,有些操作并不总是可以撤消的,所以请务必谨慎小心,一旦失误&#xff0c…

大连理工大学软件学院2022年秋季学期《矩阵与数值分析》上机作业

文章目录 《计算机科学计算》第二版162页第12题(1)162页第16题216页第12题 《数值分析方法与应用》一、基础知识部分1、5、 二、线性方程组求解2、6、 三、非线性方程组求解1、4、 四、插值与逼近1、5、7、 五、数值积分2、 六、微分方程数值解法1、 《计…

com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The

配置文件示例: # SQL Server 数据源配置 spring.datasource.dynamic.datasource.sqlserver.urljdbc:sqlserver://100.100.0.0\\shili;databaseNamecs; spring.datasource.dynamic.datasource.sqlserver.usernamesa spring.datasource.dynamic.datasource.sqlserver.password sp…

C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果

C#,入门教程(01)—— Visual Studio 2022 免费安装的详细图文与动画教程https://blog.csdn.net/beijinghorn/article/details/123350910 C#,入门教程(02)—— Visual Studio 2022开发环境搭建图文教程https://blog.csdn.net/beijinghorn/article/detail…

毫秒格式化

## 计算当前毫秒数: const [start,setStart] useState(new Date().getTime())useEffect(()>{setInterval(()>{setCurrMill(new Date().getTime()-start)},1)},[]) ## 格式化毫秒 function formatMilliseconds(milliseconds) {const totalSeconds Math.flo…

WEB 3D技术 three.js通过 GLTFLoader 导入并应用 gltf/glb 3D资源

上文 WEB 3D技术 three.js 雾 基础使用讲解我们讲了雾的基本使用方法 但是 如果我们要做一个树林 一颗一颗树去加 那真的是要累死了 我们一定是在建模软件上 建模好这样的模型 然后将模型导入到场景中 官网中搜索 GLTFLoader 在我们日常WEB开发中 用的最多的3D格式 就是 GLTF…

门控循环单元(GRU)-多输入时序预测

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、部分代码: 四、完整代码数据下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平台编译…

【一分钟】ThinkPHP v6.0 (poc-yaml-thinkphp-v6-file-write)环境复现及poc解析

写在前面 一分钟表示是非常短的文章,只会做简单的描述。旨在用较短的时间获取有用的信息 环境下载 官方环境下载器:https://getcomposer.org/Composer-Setup.exe 下载文档时可以设置代理,不然下载不上,你懂的 下载成功 cmd cd…

骑砍战团MOD开发(29)-module_scenes.py游戏场景

骑砍1战团mod开发-场景制作方法_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Cw411N7G4/ 一.骑砍游戏场景 骑砍战团中进入城堡,乡村,战斗地图都被定义为场景,由module_scenes.py进行管理。 scene(游戏场景) 天空盒(Skyboxes.py) 地形(terrain code) 场景物(scene_…

跨境电商的语言障碍:翻译工具的必要性

随着全球化的加速和电子商务的普及,跨境电商逐渐成为企业拓展市场的重要渠道。然而,跨境电商在带来无限商机的同时,也面临着语言障碍的挑战。由于不同国家和地区的语言和文化差异,跨境电商在产品描述、用户沟通、广告宣传等方面需…

ETL项目实战--学习笔记

ELT基本概念 1,什么时ELT? E: Extract,数据抽取 > 抽取的是其他数据源中的数据 T: Transform,数据转换 > 将数据转换为统一的格式,消除异常值,缺失值,对于错误的逻辑进行修改 L: Load,数据加载 > 将不同数据…

RAID的介绍和选择

RAID 类型:什么是 RAID 以及哪种 RAID 级别适合您? 一、RAID 简介 在2021年6月11日,亚瑟迪特纳进行了一场关于RAID技术的技术讲座。RAID,即独立磁盘冗余阵列,是将多个硬盘驱动器协同工作的技术。不同的RAID类型各有优…

双指针刷题(三)

所有算法文章链接(最底部) http://t.csdnimg.cn/IbllR 1.有效三角形个数 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 1.分析题意 给一个非负的数组,判断这个数组能组成多少个三角形。 2.解题思路 补充知识…

如何获取 ChatGPT 的 OpenAI API 密钥

为什么需要 OpenAI API 密钥? 拥有 OpenAI API 密钥可以解锁多种强大的功能。您可以享受以下一些好处: 访问先进的人工智能模型 OpenAI 开发了 GPT-3 和 Codex 等多种先进的人工智能模型。借助 API 密钥,您可以利用这些模型的功能来执行自然…

【Java】ThreadLocal原理与使用场景

ThreadLocal原理: 字段: //ThreadLocal对象的哈希码 private final int threadLocalHashCode nextHashCode();//生成ThreadLocal对象的哈希码时,需要用到该对象,从0开始 private static AtomicInteger nextHashCode new Atomic…

文件分片上传(模拟网盘效果)

文件分片上传(模拟网盘效果) 文章说明简单模拟拖拽文件夹和选择文件的进度条效果效果展示结合后端实现文件上传效果展示加上分片的效果效果展示加上MD5的校验,实现秒传和分片的效果后续开发说明源码下载 文章说明 文章主要为了学习文件上传&a…

图像拼接——基于homography的特征匹配算法

目录 1. 任务要求2. 数据集3. 基于homography的特征匹配算法4. 拼接流程展示4.1 图片实例4.2 特征点位图4.3 特征点匹配结果4.4 相机校准结果4.5 拼接结果 5. 部分图像拼接结果展示 1. 任务要求 输入:同一个场景的两张待拼接图像(有部分场景重合&#x…

统信系统常见问题解决方法

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 背景说明 本文所说的问题,是基于浪潮统信UOS的环境存在的问题。 一、WPS新建文档默认保存格式不对 解决办法: 1.编辑/opt/apps/cn.wps.wps-office-pro/files/kingsoft/wps-office/…

计算机网络【Google的TCP BBR拥塞控制算法深度解析】

Google的TCP BBR拥塞控制算法深度解析 宏观背景下的BBR 慢启动、拥塞避免、快速重传、快速恢复: 说实话,这些机制完美适应了1980年代的网络特征,低带宽,浅缓存队列,美好持续到了2000年代。 随后互联网大爆发&#x…

【中南林业科技大学】计算机组成原理复习包括题目讲解(超详细)

来都来了点个赞收藏关注一下再走呗🌹🌹🌹🌹 第1章:绪论 1.冯诺依曼机特点,与现代计算机的区别 冯诺依曼计算机的基本思想是:程序和数据以二进制形式表示,存储程序控制。在计算机中&…