Redis五大数据类型的底层设计

news/2024/5/20 4:15:15/文章来源:https://blog.csdn.net/dougongzi/article/details/133818927

SDS

  • 无论是 Redis 的 Key 还是 Value,其基础数据类型都是字符串。
  • 虽然 Redis是使用标准 C 语言开发的,但并没有直接使用 C 语言中传统的字符串表示,而是自定义了一 种字符串。这种字符串本身的结构比较简单,但功能却非常强大,称为简单动态字符串,Simple Dynamic String,简称 SDS。

SDS 结构

SDS 不同于 C 字符串。C 字符串本身是一个以双引号括起来,以空字符’\0’结尾的字符序 列。但 SDS 是一个结构体,定义在 Redis 安装目录下的 src/sds.h 中:

struct sdshdr { 
// 字节数组,用于保存字符串 
char buf[]; 
// buf[]中已使用字节数量,称为 SDS 的长度 
int len; 
// buf[]中尚未使用的字节数量 
int free; 
} 

在这里插入图片描述
通过以上结构可以看出,SDS 的 buf 值实际是一个 C 字符串,包含空字符’\0’共占 6 个字 节。**但 SDS 的 len 是不包含空字符’\0’的。
**

SDS 的优势

  • 对于 C 字符串,若要获取其长度,则必须要通过遍历整个字符串才可获取到的。对于超 长字符串的遍历,会成为系统的性能瓶颈。 SDS 结构体中直接就存放着字符串的长度数据

  • SDS 采用了空间预分配策略惰性空间释放策略来避免内存再分配问题。

  • 空间预分配策略是指,每次 SDS 进行空间扩展时,程序不但为其分配所需的空间,还会 为其分配**额外的未使用空间,以减少内存再分配次数。**而额外分配的未使用空间大小取决于 空间扩展后 SDS 的 len 属性值。

    • 如果 len 属性值**小于 1M,**那么分配的未使用空间 free 的大小与 len 属性值相同。
    • 如果 len 属性值大于等于 1M ,那么分配的未使用空间 free 的大小固定是 1M。
  • SDS 对于空间释放采用的是惰性空间释放策略

    • 该策略是指,SDS 字符串长度如果缩短, 那么多出的未使用空间将暂时不释放,而是增加到 free 中。以使后期扩展 SDS 时减少内存 再分配次数。 如果要释放 SDS 的未使用空间,则可通过 sdsRemoveFreeSpace()函数来释放。

集合的底层实现原理

  • Redis 中对于 Set 类型的底层实现,直接采用了 hashTable。hashtable就是普通的哈希表(key为set的值,value为null)。
  • 但对于 Hash、ZSet、List 集 合的底层实现进行了特殊的设计,使其保证了 Redis 的高性能。

1 两种实现的选择

  • 对于Hash与ZSet集合,其底层的实现实际有两种:压缩列表zipList,与跳跃列表skipList。
  • 这两种实现对于用户来说是透明的,但用户写入不同的数据,系统会自动使用不同的实现。 只有同时满足以配置文件 redis.conf 中相关集合元素数量阈值与元素大小阈值两个条件****,使用的就是压缩列表 zipList,只要有一个条件不满足使用的就是跳跃列表 skipList。、
  • 例如,对于ZSet 集合中这两个条件如下:
    • 集合元素个数小于 redis.conf 中 zset-max-ziplist-entries 属性的值,其默认值为 128
    • 每个集合元素大小都小于 redis.conf 中 zset-max-ziplist-value 属性的值,其默认值为 64字节

2什么是 zipList

zipList,通常称为压缩列表,是一个经过特殊编码的用于存储字符串或整数的双向链表。 其底层数据结构由三部分构成:**head、entries 与 end。**这三部分在内存上是连续存放的。 在这里插入图片描述

  • prevlength:该部分用于记录上一个 entry 的长度,以实现逆序遍历
  • encoding:该部分用于标志后面的 data 的具体类型。如果 data 为整数类型,encoding固定长度为 1 字节。如果 data 为字符串类型,则 encoding 长度可能会是 1 字节、2 字 节或 5 字节。data 字符串不同的长度,对应着不同的 encoding 长度。(压缩的体现)。

什么是** skipList

skipList,跳跃列表,简称跳表,是一种**随机化的数据结构,基于并联的链表,**实现简单, 查找效率较高。简单来说跳表也是链表的一种,只不过它在链表的基础上增加了跳跃功能。 也正是这个跳跃功能,使得在查找元素时,能够提供较高的效率。

skipList 原理

假设有一个带头尾结点的有序链表。
在这里插入图片描述
为了提升查找效率,在偶数结点上增加一个指针,让其指向下一个偶数结点。
在这里插入图片描述
这样所有偶数结点就连成了一个新的链表(简称高层链表),当然,高层链表包含的节 点个数只是原来链表的一半。此时再想查找某个数据时,先沿着高层链表进行查找。当遇到 第一个比待查数据大的节点时,立即从该大节点的前一个节点回到原链表中进行查找。
在这里插入图片描述
问题:这种对链表分层级的方式从原理上看确实提升了查找效率,但在实际操作时就出现了问 题:由于固定序号的元素拥有固定层级,所以列表元素出现增加或删除的情况下,会导致列表整体元素层级大调整,但这样势必会大大降低系统性能。

优化

为了避免前面的问题,skipList 采用了随机分配层级方式。即在确定了总层级后,每添 加一个新的元素时会自动为其随机分配一个层级。这种随机性就解决了节点序号与层级间的 固定关系问题。
在这里插入图片描述

  • 上图演示了列表在生成过程中为每个元素随机分配层级的过程。从这个 skiplist 的创建 和插入过程可以看出,每一个节点的层级数都是随机分配的,而且新插入一个节点不会影响 到其它节点的层级数。
  • 只需要**修改插入节点前后的指针,**而不需对很多节点都进行调整。这 就降低了插入操作的复杂度。

什么是 quickList

  • List的底层实现: quickList,快速列表,quickList 本身是一个双向无循环链表,它的每一个节点都是一个zipList

  • quickList 本质上是 zipList 和 linkedList 的混合体。其将 linkedList 按段切分,每一段使用 zipList 来紧凑存储若干真正的数据元素,多个 zipList 之间使用双向指针串接起来。当然, 对于每个 zipList 中最多可存放多大容量的数据元素,在配置文件中通过 list-max-ziplist-size属性可以指定。
    在这里插入图片描述

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

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

相关文章

出差学知识No4:ubuntu vim中的各种必须掌握的经典操作(持续更新......)

1、给vim模式下打开的文档内容每行之前加上行号,便于问题定位 1、给vim模式下打开的文档内容每行之前加上行号,便于问题定位 摁一下Esc之后输入:set number

嵌入式SoC降低能够有效降低电力线表应用的成本

用于基于FSK的电力线通信(PLC)。MB87S2090和MB87S2090-F与ADD Semiconductor,电力线通信嵌入式SoC的开发商以及用于自动仪表管理的解决方案联合开发。两种器件都与ADD Semiconductor的设计引脚兼容。 MB87S2090是一种电力线通信嵌入式SoC&am…

分享一下微信报名系统怎么做

微信报名系统是一种基于微信公众号或小程序的开发和应用,可实现用户通过微信进行在线报名、支付等操作的系统。本文将介绍微信报名系统的基本概念、制作流程、功能特点、使用流程和推广策略,帮助读者了解如何制作一个高效的微信报名系统。 一、微信报名系…

记一次U8登录异常问题

最近陆续有同事反映U8系统登录切换不同用户,在选择账套时U8长时间无反应。 一开始在经历二十多秒的等待后还会出现账套下拉列表选项,后来经历更长的时间等待后提示连接SQL服务器错误,如下图: 因为不切换用户时直接登录使用是没有…

11 | JpaRepository 如何自定义

EntityManager 介绍 Java Persistence API 规定,操作数据库实体必须要通过 EntityManager 进行,而我们前面看到了所有的 Repository 在 JPA 里面的实现类是 SimpleJpaRepository,它在真正操作实体的时候都是调用 EntityManager 里面的方法。…

如何避免输入中文拼音时触发input事件

如何避免输入中文拼音时触发 input 事件 html 结构 <input type"text" name"" id"" />js 定义了一个输入框并添加了三个事件监听器。以下是每个部分的解释&#xff1a; const input document.querySelector("input"); let i…

CentoS7 安装篇十二:mysql主从搭建(xtrackbackup不停机搭建)

一、mysql主从搭建使用mysql自身自己做&#xff0c;需要停止mysql服务进行&#xff0c;这种情况下面临以下问题 1.影响客户正在运行的软件&#xff0c;数据库比较大的情况下耗时时间长 2.如果不想影响客户使用体验&#xff0c;就是晚上加班搞 为了更好软件体验及避免加班情况&a…

以任意位置中间元素翻转字符串:

前置知识&#xff1a; 你要学会如何将字符串转化为字符&#xff0c;如何将字符转为字符串 字符串转化为字符 String str "abcdef";char[] strChar str.toCharArray();for(int i :strChar){System.out.print((char)i" ");//需要进行强制类型转换&#x…

Docker逃逸---SYS_PTRACE浅析

一、产生原因 用户授予了容器SYS_PTRACE权限&#xff0c;并且与宿主机共享一个进程命名空间(--pidhost)&#xff0c;使得容器内可以查看到宿主机的进程&#xff0c;攻击者可以利用进程注入&#xff0c;反弹shell&#xff0c;从而实现逃逸 二、利用条件 1、容器有SYS_PTRACE权…

Vue3集成高德地图:快速上手,实现你的业务需求

Vue3集成高德地图 前言一、准备工作1.开发文档2.添加应用 二、使用步骤命令安装2.地图容器创建3.组件引入4.js api 安全密钥5.初始化地图6. 图层6.1 添加 / 设置 / 获取 / 移除图层6.1.1 添加图层6.1.2 设置图层6.1.3 获取图层6.1.4 移除图层 7. 点标记8. 信息窗体8.1 默认信息…

【MATLAB源码-第47期】基于matlab的GMSK调制解调仿真,输出误码率曲线,采用相干解调。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 GMSK&#xff08;高斯最小移相键控&#xff09;是数字调制技术的一种。下面是关于GMSK调制解调、应用场景以及其优缺点的详细描述&#xff1a; 1. 调制解调&#xff1a; - 调制&#xff1a;GMSK是一种连续相位调制技术&am…

东风新能源电动汽车E60/E70在驾培驾考领域的CAN数据应用

最近几年&#xff0c;我国驾培行业新增学员数量保持了三年的持续下降&#xff0c;与此同时&#xff0c;教学车辆和驾驶培训机构数量则在持续上升&#xff0c;由此可见驾培市场呈现出不平衡的状态&#xff0c;供大于求已经成为常态。 现在的年轻人&#xff0c;并不把开车作为职…

传统鞋业焕发智造魅力,健康鞋步力宝品牌数字化转型助力多方把控

随着经济环境的变化以及市场竞争的加剧&#xff0c;加之我国劳动力、土地以及资源环境成本的快速上升&#xff0c;以劳动密集型为主、通过低附加值方式发展的传统产业集群遭遇瓶颈。而数字化时代的到来&#xff0c;不仅给各行各业带来了巨大的变革&#xff0c;也为传统鞋服业带…

Kafka基础入门

Kafka介绍 Kafka是什么&#xff1f; kafka是一种分布式的&#xff0c;基于发布/订阅的消息系统。 Kafka的特点 分布式&#xff0c;吞吐量高&#xff0c;发布订阅模式&#xff0c;轻量灵活&#xff0c;较长时间持久化 Kafka的应用场景 解耦 原先一个微服务是通过接口&…

ASP.NET LIMS系统全套源码(演示+自主版权+项目使用)

基于ASP.NET Dotnet 3.5 EXT.NETMSSQL 2018技术架构开发的LIMS系统全套源码&#xff08;演示自主版权项目使用&#xff09; LIMS是为检测组织全流程业务设计的。以实验室为中心&#xff0c;将实验室的业务流程、环境、人员、仪器设备、标物标液、化学试剂、规范办法、图书资料、…

vm虚拟机克隆ubuntu

1. 使用vm虚拟机自带的克隆功能 2. 选择完整克隆&#xff0c;然后选择您克隆到哪里的目录 3. 点击编辑你克隆后的虚拟机&#xff0c;点网络适配器&#xff0c;然后点高级&#xff0c;点击生成mac地址&#xff08;由于唯一&#xff0c;所以需要重新生成&#xff09; 4. 开启虚拟…

【mfc/VS2022】计图实验:绘图工具设计知识笔记2

按钮添加处理程序 1.类视图找到对应类右击&#xff0c;类向导 2. 找到对应的的按钮id 如何将画出的两个相交的圆都显示出来&#xff0c;而不是重叠&#xff08;如下图&#xff09;隐藏了一条圆弧 问题如图&#xff1a; 因为矩形和圆心其实是个背景色的封闭图形&#xff0c;所…

阿里企业邮箱能发开发信吗?群发邮件技巧?

阿里企业邮箱如何群发营销邮件&#xff1f;邮箱发开发信的方法&#xff1f; 对于许多企业而言&#xff0c;开发信是一种重要的沟通工具&#xff0c;用于与客户、合作伙伴和供应商建立联系。在本文中&#xff0c;蜂邮EDM将探讨阿里企业邮箱是否支持发送开发信&#xff0c;以及如…

解决安装nvm以后windows cmd无法找到npm/yarn命令的问题

安装了nodejs多版本管理工具nvm以后&#xff0c;会出现windows cmd无法找到npm/yarn命令的问题 只要一运行npm/yarn就会提示&#xff1a;不是内部命令&#xff0c;找不到运行路径之类的。 解决办法&#xff1a;首先打开windows环境变量的配置&#xff0c;查看NVM_SYMLINK指向…

第三章 内存管理 三、覆盖与交换

目录 一、覆盖技术 二、交换技术 三、总结 一、覆盖技术 1、在覆盖技术中&#xff0c;我们要找到程序的调用结构。 2、因为这些程序不可能同时被调用&#xff08;互斥调用&#xff09;&#xff0c;所以我们只需要选出需要空间最大的程序。 3、在物理内存中开拓一片与最大程…