Redis五大数据结构的底层实现(未完成)

news2024/11/23 23:53:56

一)String类型:可以使用object encoding name就可以查看字符串的编码

SDS,flags的值不同,那么len和alloc所表示的值的数据范围也不同,所以flags的只是为了标识SDS头的总大小;

alloc和len刚开始进行申请内存空间的时候都是相同的

String是redis中最常见的数据结构类型:

1)最基本的编码方式是RAW,是基于简单动态字符串来实现的,存储上线是512mb,每一次存储一个String类型的数据的时候,需要先申请内存创建一个RedisObject的内存空间,再申请SDS的内存空间,申请的时候有两次内存的申请,释放的时候也是有两次内存的释放;

 2)如果存储的SDS的长度是小于44个字节的,那么会直接采用EMBSTR编码,此时的ObjectHead和SDS是一段连续的内存空间,申请内存的时候只是需要调用一次内存分配函数即可(因为每一次分配内存都要涉及到用户态和内核态的切换) 

SDS一共占用48个字节,RedisObject占用16个字节,一共是64个字节(不会超过64字节),Redis在底层采用的内存分配算法是以2^N来做内存分配的,64恰好是一个分片大小,就不会产生内存碎片,所以实际使用String类型的时候,尽量字符串长度小于44字节

3)如果进行存储的字符串是整数值,况且在Long_Max范围内,底层就会使用INT编码,直接将数据存储在RedisObject的指针位置(指针刚好8个字节),就不需要SDS了

Redis中的List数据结构

Redis的List类型可以从首和尾进行操作元素

哪一个数据结构可以满足以上特征呢 

1)使用普通双向链表,可以从双端进行访问内存占用比较高,内存碎片比较多

2)使用ZipList,可以从双端进行访问,内存的占用比较低,存储的上限比较低,双端访问不是基于指针实现的,而是记录每一个结点的大小,推算出内存地址的,因为他是申请连续内存空间的,如果数据量不多还可以,但是如果数据量过大,申请较大的连续内存空间效率可能非常低,所以是不建议使用ZipList来存储过多的数据的,只能存储少量数据

3)QuickList:底层是使用双端链表+压缩列表,可以从双端进行访问,内存占用是比较低的,包含多个Ziplist,存储上限较高,双端列表的每一个节点不是数据而是一个ZipList

3.1)在3.2版本之前,Redis使用ZipList(只能存储少量数据)和LinkedList来实现List,当元素数量小于512况且元素大小小于64字节的时候采用ZipList编码,超过使用LinkedList编码;

3.2)在3.2版本以后,Redis统一使用QuickList来实现List;

1)上面这个方法是通用的插入方法,where是队首或者是队尾,lpush和rpush底层都是调用的pushGenericCommand方法,最后的这个xx参数,如果你进行传递了,也就是true,只有当前的key存在,才会执行push命令,如果不存在,一般是不会传递的,也就是当你第一次进行插入的时候,key不存在,就会自动创建这个key,并分配内存空间;

2)第一个参数client代表客户端,当redis的客户端和服务端建立连接的时候,都会被封装成一个client对象,里面包含着客户端的各种信息,包括客户端要执行的命令,每一个命令都会被分成N段(lpush key value l1 l2 l3),命令本质上就是一个一个的字符串,每一个字符串会使用空格隔开,分成多个命令段放到一个数组中,也就是argv数组,其实最后执行命令的时候,就是从c里面的argv数组中取出一个一个的参数命令段,拼接成完整命令执行;

3)j=2开始遍历是在寻找未来可以存放在list中的元素,里面的if语句是针对用户传递过来的针对于元素大小的校验,argc就是整个argv数组元素的个数;

4)lookupkeywrite方法是在寻找你要向list集合中的哪一个key进行push,第一个参数是c->db,是客户端要进行访问哪一个数据库,取出当前客户端要访问的数据库,第二个参数在数据库中去选择对应key去寻找对应的value(list);

最终方法的返回值是一个RedisObject对象(list)

5)然后去进行检查当前类型是否是一个List类型,根据RedisObject中的type属性来检查当前对象的类型,如果不是list类型直接返回;

6)如果RedisObject不存在并且xx为true,说明没有list就直接返回了;

7)否则就会在createQuickList中创建一个全新的List:

8)createObject方法底层创建了一个全新的RedisObject对象,并将RedisObject中数据的指针指向创建的新的list,并在方法底层针对RedisObject设置全新的编码和类型;

 

9)最后的quicklistsetoptions中限制QuickList中每一个ZipList的大小,是否压缩,server.list_compress_depth是压缩深度,如果是0表示不进行压缩,如果是1表示QuickList的首尾各有一个不压缩,中间节点压缩,如果是2表示QuickList的首尾各有两个节点不压缩,中间节点压缩

10)dbAdd方法是真正的添加元素

Redis中的Set数据结构:对元素的查询效率非常高

Set是Redis中的单列集合,包括以下特点:

1)不保证有序性

2)保证元素唯一

3)求并集,差集,补集

1)首先就是跳表, 查询性能比较不错,但是不太合适,首先跳表要去根据score值进行排序,但是Set集合不需要有序,但是Set集合中还没有score值;

2)Set是Redis中的集合,不一定保证元素有序性,但是需要保证元素唯一,对查询性能要求极高,为了保证查询效率和唯一性,set使用dict编码,dict中的key用来存储元素,value统一使用null;

3)当存储的Set集合里面全部都是整数的时候,并且元素数量不超过set-max-intset-entries的时候,底层默认使用的是IntSet编码,是连续存储空间,元素数量也不能太多,从而来节省内存;

1)subject就是一个RedisObject对象,里面的编码可能是Inset或者是dict,第二个参数是要插入的值

2)进行新增元素的时候如果RedisObject中的编码是HT编码,那么直接插入元素value即可

3)如果RedisObject中的编码类型是IntSet那么直接判断当前value是否是整数,如果是整数,直接添加元素到IntSet里面,如果此时添加元素成功了,直接判断当前元素个数是否大于了set-max-intset-entries的值,如果大于,那么直接将编码转换成HT

4)如果value值不是整数直接转换成HT编码;

 

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

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

相关文章

简谈你对synchronized关键字的使用

👨‍🎓作者:bug菌 ✏️博客:CSDN、掘金、infoQ、51CTO等 🎉简介:CSDN|阿里云|华为云|51CTO等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12…

Word控件Spire.Doc 【其他】教程(4):在 Word 中插入上标和下标

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具,专注于创建、编辑、转…

5.2.1 分类的IP地址

5.2.1 分类的IP地址 通过前面的学习我们知道IPv4协议中包含的内容非常的多,我们学习IPv4又分为几个方面 介绍分类的IP地址IP地址的分配与使用IP分组的格式因特网地址到物理地址的映射(ARP协议),用以动态完成IP地址到物理地址映射…

时间序列预测 | Matlab基于灰狼算法优化支持向量机(GWO-SVM)的时间序列预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列预测 | Matlab基于灰狼算法优化支持向量机(GWO-SVM)的时间序列预测 评价指标包括:MAPE、MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %----------------

别再纠结页面设计!挑选小程序页面设计模板就对了

小程序页面设计模板可以是一个非常棒的选择,特别是如果你想要快速创建一个优秀的小程序。 以下是一些关于如何选择小程序页面设计模板的建议: 确定你的需求:在开始挑选小程序页面设计模板之前,你需要明确你的需求。确定你的小程…

下载安装LabVIEW

下载安装LabVIEW 介绍下载安装流程下载安装 后续 介绍 LabVIEW 是 工程 师 用来 开发 自动 化 研究、 验证 和 生产 测试 系统 的 图形 化 编 程 环境。Labview作为图形化编程语言,图形控件拖拽式编程,显得更加直观形象,也很容易上手学习。 …

pytorch 绘制一维热力图

热力图 热力图(Heat Map)是指用 X 轴 和 Y 轴 表示的两个分类字段确定数值点的位置,通过相应位置的矩形颜色去表现数值的大小,颜色深代表的数值大。 热力图是非常特殊的一种图,可以显示不可点击区域发生的事情。热力…

3.5. 异常处理

在Java中,异常是一种用于表示程序在运行过程中遇到的错误或异常情况的对象。Java提供了一套异常处理机制,可以帮助我们更好地处理运行时可能出现的错误和异常。异常处理的主要概念包括: 异常类:Java中的异常类是继承自Throwable类…

L1频段卫星导航射频前端低噪声放大器芯片 AT2659/AT2659S

AT2659 是一款具有高增益、低噪声系数的低噪声放大器(LNA)芯片,支持L1频段多模式全球卫星定位,可以应用于GPS、北斗二代、伽利略、Glonass等GNSS导航接收机中。芯片采用先进的SiGe工艺制造,采用1.5 mm X 1 mm 0.78 mm的…

招标采购评标专家管理数智化解决方案

评标专家作为评标活动的重要一环,对保证评标活动的公平公正和评标质量,乃至提升营商环境都意义重大。 为了加强招采过程中评标专家的监督管理、健全评标专家库制度,保证评标活动的公平公正,提高评标质量,国家出台了相…

Pytest 高级进阶用法Hook使用pdm打包成插件

系列文章目录 提示:阅读本章之前,请先阅读目录 文章目录 系列文章目录前言一、创建项目二、安装pdm三、使用pdm创建项目四、创建src五、src下面,再创建包名六、编写plugin七、编写配置pyproject.toml八、使用pdm,添加pytest到该插…

如何看待人工智能?——比尔盖茨谈智能时代的机遇与挑战

原创 | 文 BFT机器人 01 比尔盖茨称AI将颠覆搜索、购物网站 “你永远不会去搜索网站了,也不会再去亚马逊了。” 当地时间5月22日,盖茨在出席一场关于AI的活动时表示,未来的顶级AI助理将颠覆现有互联网使用方式,替代人们执行某些任…

PHPMySQL基础(三):处理查询SQL返回的结果集

PHP&MySQL基础(一):创建数据库并通过PHP进行连接_长风沛雨的博客-CSDN博客 PHP&MySQL基础(二):通过PHP对MySQL进行增、删、改、查_长风沛雨的博客-CSDN博客 目录 一、连接MySQL,处理错误,统一字…

面了个4年经验的测试,自动化都不会,真是醉了····

最近面试了一个 4 年测试经验的测试工程师,简历和个人介绍都提到了会自动化,于是我就问了几个自动化方面的问题: 在自动化测试中,你是如何选择和设计测试用例的?你使用过哪些自动化测试工具,如何选择自动化…

从C语言到C++_14(vector的常用函数+相关选择题和OJ题)

目录 1. vector的常用函数 1.1 vector 的介绍 1.2 vector 的初始化 1.3 vector 的操作和遍历 1.4 vector 的容量和增删查改 2. vector 相关笔试题 3. vector 相关OJ题 136. 只出现一次的数字 - 力扣(LeetCode) 解析代码: 118. 杨辉…

华为OD机试真题B卷 Java 实现【求解立方根】,附详细解题思路

一、题目描述 计算一个浮点数的立方根,不使用库函数。保留一位小数。 数据范围:∣val∣≤20 。 二、输入描述 待求解参数,为double类型(一个实数) 三、输出描述 输出参数的立方根。保留一位小数。 四、解题思路…

【九】设计模式~~~结构型模式~~~外观模式(Java)

【学习难度:★☆☆☆☆,使用频率:★★★★★】 4.1. 模式动机 不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶、茶具和开水,如图1(A)所示,而去茶馆喝茶,最…

从自动化到测开,测试人员逆袭之路从此起步...

在当今竞争激烈的软件测试行业中,近期的招聘市场确实面临一些挑战。大量的求职者争相涌入岗位,许多热衷于功能测试的人士甚至难以找到理想的工作机会。更不幸的是,连自动化测试和性能测试这些专业领域也受到了测试开发人员的竞争压力。然而&a…

jvs-rules 规则引擎-变量管理(函数式)的配置说明

JVS规则引擎变量管理 变量在规则引擎中的作用 数据存储和共享:变量配置允许在规则引擎中存储和访问数据。通过定义变量,可以将数据存储在规则引擎中,使其可供规则和决策过程使用。这样可以消除重复数据存储的需求,提高数据的共享…

ipad手写笔什么牌子好?最好用的电容笔

由于Apple pencil太过昂贵,很多小伙伴想入手一支电容笔,但是国内的品牌众多,不知道该如何挑选出合适自己的电容笔,我们在挑选电容笔要注意一些事项,才能挑选出合适的电容笔,今天给大家总结几个点再给大家介…