Redis集合底层实现原理
目录
- 本章重点
- 简单动态字符串SDS
- 集合底层实现原理
- zipList
- listPack
- skipList
- quickList
- Key 与Value中元素的数量
本章重点
- 掌握Redis简单动态字符串
- 了解Redis集合底层实现原理
简单动态字符串SDS
- SDS简介
我们Redis中无论是key还是value其数据类型都是字符串.我们Redis中的字符串是如何存储的呢?虽然我们的Redis是用C语言开发的,但是并没有直接套用其字符串形式.自定义了一种字符串.这种字符串结构简单,功能强大,称为简单动态字符串(Simple Dynamic String) 简称SDS
Redis中的字符串并非都是SDS,字面常量是C字符串
- SDS结构
SDS是一个结构体,定义在Redis安装目录下的
src/sds.h
中
sturct sdshdr
{//字节数组,用于保存字符串char buf[];//buf[]中已使用的字节数量,称为SDS长度int len;//buf[]中尚未使用的字节数量int free;
}
我们可以查看src/sds.h
定义
例如我们执行一个set name "hello redis"
命令时,这里的字符串是字面常量,在Redis存储方式如下:
这里的\0
是需要储存在buf中的,但是不记录长度len!
- SDS优势
- 字符串长度获取性能高,无需遍历字符串
- 保证二进制安全,我们的C字符串真能在字符串结尾出现
\0
,而在图片,音频,视频等二进制文件数据以\0
作为分隔符情况很是常见,所以C字符串无法保存其二进制数据,而SDS可以通过len判断字符串结尾位置.读取到什么,就存储,无需其他过滤操作即可!- 减少内存再分配次数,SDS采用了空间预分配策略和惰性空间释放策略,来避免再分配空间问题!
1.如果len<1M,那么free空间大小和len相同.
2.len>=1M,free固定大小=1M
如果sds长度len减小,那么free也不会释放,等到后期再次分配使用
如需释放可以手工调用函数释放- 兼容C函数
因为保留的C语言的\0
我们的SDS也可以使用C语言字符串函数 strcmp等
- 常用的SDS操作函数
集合底层实现原理
Redis中对于Set类型底层的实现,直接采用了hashTable,但是对于Hash,Zset,List集合的底层进行了特殊设计,保证Redis的高性能
- 2种实现的选择
对于Hash和Zset集合,其底层实现实际有2种:压缩
zipList
和跳跃列表skipList
这两种实现,用户都是透明的,系统会根据用户写入数据的不同,选择不同的的实现.只有同时满足了配置文件redis.conf中配置d相关集合元素个阈值和元素大小阈值两个条件使用的就是压缩链表zipList
.例如Zset集合满足下面2个条件就是zipList
- 集合元素个数
小于
redis.conf 中zset-max-ziplist-entries
属性的值,其默认值为128
- 每个集合元素大小都
小于
redis.conf 中zset-max-ziplist-value
属性的值,其默认值为64
字节
zipList
-
zipList
zipList通常称为压缩链表,是经过特殊编码的用于存储字符串或整数的的双向链表.其底层由3部分构成!
head,entries,end.这3部分在空间上是连续存放的.- head
head由3部分构成:
- zlbytes:占4个字节,用于存放整个ziplist的数据结构所占字节数,包括zlbytes本身长度!
- zltail:占用4个字节,用于存放最后一个entry在整个数据结构的偏移量(字节)可以快速定位列表尾位置,以便操作!
- zllen:占2个字节,用于存放列表包含的entry个数,由于只有16位,所有最多ziplist只能有65535个entry
- entries
entries是真正的列表,由很多的entry元素构成,由于不同的元素类型,数值的不同,从而导致entries的长度不同,entry也由3部分构成
- prevlength:记录上一个entry的长度,用于实现逆序遍历,默认长度为1个字节,如果上一个entry长度大于了254字节,prevlength就会扩展到3个字节
- encoding:该部分用于标志后面的data数据类型,如果data是整数,encoding部分长度为1个字节,如果是字符串类型,那么可能为1个字节/2/5个字节长度,由于data数据长度的不同对应的encoding长度也不同.
- end
end自包含一部分zlend占1个字节,是ziplist的结束标志. 二进制8个1固定255!
listPack
- listPack
对于我们的ziplist的entry结构,由于其实现的逆序遍历,保存了前一个entry的大小,如果进行了中间修改或者插入操作,会导致级联更新,影响性能.为了实现更紧凑,更快解析,更简单的实现,重写了实现了ziplist命名为listPack.
在Redis7.0已经将zipList全部替换成了listPack,为了兼容保留了zipList的相关属性!
listPack结构
listPack是经过特殊编码的用于存储字符串或整数的双向链表.底层数据结构也由其3部分构成!
- head
head由2部分构成:
- totalBytes:占4个字节,用于存放listPack整个数据结构包含其本身长度,单位是字节
- elemNum:占2个字节,用于保存entry元素个数,最多为65535个!
- entry
这里就是和zipList的区别之处,这里没有了prevlength,增加了记录当前长度的element-total-len也可实现逆序遍历.而不会引发级联更新
- encoding:该部分用于标志后面的data的具体类型。如果data为整数类型,encoding 长度可能会是1、2、3、4、5或9字节。不同的字节长度,其标识位不同。如果data 为字符串类型,则encoding长度可能会是1、2或5字节。data字符串不同的长度,对应着不同的encoding长度。
- data:真正存储数据的位置,整数或者字符串类型,不同数据占用的字节长度不同
- element-total-len:记录当前entry长度,用于实现逆序遍历.可能的值[1,5]字节
- end
这里的end和zlend一样,都是结束标志,255,8个二进制1构成
skipList
- skipList
跳跃列表,简称跳表,是一种随机化的数据结构,基于并联的链表.实现简单,查询效率高.就是链表的一种不过在此基础上实现了跳跃功能.使得在查找元素具有较高的速率!
- 原理
skipList就是在list基础上随机增加一些高层指针,高层指针遍历效率高,层级越高,查找效率越高!我们可以先在高层遍历,然后再向下层级遍历查找指定位置
- 算法优化
这里的层级采用随机的方式,就有效的避免了按照指定规定元素个数的层级方式,插入或修改元素需要对链表的层级指针进行修改!而采用随机层级的方式就插入元素就随机层级,然后插入即可,删除也修改前后指针即可!
quickList
- quickList
快速链表,quickList本身是一个双向无循环链表.他的每一个节点都是一个zipList.由于zipList和linkedList都有明显不足,而quickList就进行了改进操作!
- 检索操作
我们的quickList可以通过zipList中head部分记录的totalNum进行检索!对其遍历的zipList的entry进行求和从而定位到指定的zipList的entry元素
- 插入操作
//设插入元素大小为: insertB
//查找到的插入位置元素大小为: zlB
//zipList最大值: zpMax
//前(后)一个元素大小: plB/nlB
1. insertB+zlB<=zpMax:
//直接插入zipList相应位置即可
2. insertB+zlB>zpMax 并且插入的位置位于元素首部位置
//2.1 insertB+plB<=zpMax:直接插入前一个元素尾部
//2.2 insetB+plB >zpMax: 构建一个新元素zipList然后连接到quickList
3. insertB+zlB>zpMax 并且插入的位置位于元素尾部位置
//3.1 insertB+nlB<=zpMax:直接插入前一个元素首部
//3.2 insetB+nlB >zpMax: 构建一个新元素zipList然后连接到quickList
4. insertB+zlB>zpMax 并且插入位置位于中间
//将当前zipList分割为2个zipList连接到quickList中,然后将元素插入到分割后的前一个元素的尾部位置
- 删除操作
直接删除即可,如果当前zipList已经没有元素了,就将当前zipList删除即可,然后修改指针连接
Key 与Value中元素的数量
- Redis最多可以处理
2^32
个key(42亿) 实际每个Redis实例可以处理至少2.5亿个key- 每个Hash,List,Set,ZSet集合都可以包含
2^32
个元素
相关文章:
Redis集合底层实现原理
目录 本章重点简单动态字符串SDS集合底层实现原理zipListlistPackskipListquickListKey 与Value中元素的数量 本章重点 掌握Redis简单动态字符串了解Redis集合底层实现原理 简单动态字符串SDS SDS简介 我们Redis中无论是key还是value其数据类型都是字符串.我们Redis中的字符…...
OVS常用命令与使用总结
OVS常用命令与使用总结 说明 在平时使用ovs中,经常用到的ovs命令,参数,与举例总结,持续更新中… 进程启动 1.先准备ovs的工作目录,数据库存储路径等 mkdir -p /etc/openvswitch mkdir -p /var/run/openvswitch …...
一以贯之:从城市网络到“城市一张网”
《论语里仁》中子曰:“参乎,吾道一以贯之”。 孔子所说的“一以贯之”,逐渐成为了中国文化与哲学的重要组成部分,指明事物发展往往需要以标准化、集约化、融合化作为目标。这种智慧在数字化发展中格外重要。从云计算、大数据技术模…...
【Java校招面试】基础知识(四)——JVM
目录 前言一、基础概念二、反射三、类加载器ClassLoader四、JVM内存模型后记 前言 本篇主要介绍Java虚拟机——JVM的相关内容。 “基础知识”是本专栏的第一个部分,本篇博文是第四篇博文,如有需要,可: 点击这里,返回…...
项目管理-计算专题(三点估算、PERT估算)
基本概念 通过考虑估算中的不确定性和风险,可以提高活动持续时间估算的准确性。这个概念源自计划评审技术(PERT)。PERT使用三种估算值来界定活动持续时间的近似区间: 最可能时间(tM):基于最可能获得的资源、最可能取得的资源生产率、对资源可用时间的现…...
【华为OD机试 2023最新 】模拟商场优惠打折(C语言题解 100%)
文章目录 题目描述输入描述输出描述用例题目解析代码思路C语言题目描述 模拟商场优惠打折,有三种优惠券可以用,满减券、打折券和无门槛券。 满减券:满100减10,满200减20,满300减30,满400减40,以此类推不限制使用; 打折券:固定折扣92折,且打折之后向下取整,每次购…...
使用TrieTree(字典树)来实现敏感词过滤
使用TrieTree(字典树)来实现敏感词过滤 1. 字典树定义 字典树(TrieTree),是一种树形结构,典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串,如01字典树)。…...
USB转串口芯片CH9101U
CH9101是一个USB总线的转接芯片,实现USB转异步串口。提供了常用的MODEM联络信号,用于为计算机扩展异步串口,或者将普通的串口设备或者MCU直接升级到USB总线。 特点 全速USB设备接口,兼容USB V2.0。内置固件,仿真标准串…...
Java语言介绍
Java是一种广泛使用的计算机编程语言,由Sun Microsystems公司于1995年推出。它是一个健壮的、面向对象的、跨平台的语言,被用于开发各种应用程序和系统,包括Web应用程序、移动应用程序、桌面应用程序、游戏以及企业级系统等。 Java具有许多优…...
终于把 vue-router 运行原理讲明白了(二)!!!
一、vue-router路由变化侦测 1.1 上一遍文章中,介绍了vue-router 的install 函数的内部实现,知道了能在this中访问$router 和视图更新的机制,文章链接终于把 vue-router 运行原理讲明白了(一)!!…...
ChatGPT实现服务器体验沙箱
服务器体验沙箱 IT 人员在学习一门新技术时,第一个入门门槛通常都是"如何在本地安装并成功运行"。因此,很多技术的官网都会通过沙箱技术,提供在线试用的 playground 或者按步模拟的 tour。让爱好者先在线尝试效果是否满足预期&…...
【算法】刷题中的位运算
作者:指针不指南吗 专栏:算法篇 🐾人类做题的过程,其实是暴搜的过程🐾 文章目录 1.位运算概述2.位运算符3.位运算应用3.1整数的奇偶性判断3.2有关 2 的幂的应用3.3lowbit(x)返回x的最后一位13.4二进制数中1的个数3.5求…...
9.Java中异常处理机制是什么
Java的异常处理通过五个关键字来实现,分别是捕获异常:try,catchsfinally;声明异常:throws;抛出异常:throw 一:try,catch捕获异常二:finally回收资源三&#x…...
GeoTools实战指南: 叠加GeoTIFF与Shapefile图层生成截图
GeoTools实战指南: 叠加GeoTIFF与Shapefile图层生成截图 介绍 本教程将介绍如何使用GeoTools库在Java中将栅格数据(GeoTIFF)与矢量数据(Shapefile)叠加显示,并将结果保存为PNG格式的图片文件。我们将解析和分析 RasterDataRenderer 类,并了解其中的每个方法和对象。 准…...
nginx配置sh脚本远程执行一键安装
背景 本地多机重复操作某些shell指令,分步执行,很耗费时间, 需要远程一键部署,傻瓜化运维,更为通用安装。 即参考docker通用安装 sudo curl https://get.docker.com | sh - # sudo python3 -m pip install docker-co…...
Excel表格成绩排名全攻略,让你事半功倍!
在学校或公司中,我们经常需要对成绩进行排名。如果手动计算排名,不仅费时费力,而且容易出错。幸运的是,Microsoft Excel提供了一个简单而快速的方法来计算和显示排名。 在学校或公司中,成绩排名是一项重要的任务。使用…...
Docker 持久化存储 Bind mounts
Docker 持久化存储 Bind mounts Bind mounts 的 -v 与 --mount 区别启动容器基于bind mount挂载到容器中的非空目录只读 bind mountcompose 中使用 bind mount 官方文档:https://docs.docker.com/storage/bind-mounts/ Bind mounts 的 -v 与 --mount 区别 如果使用…...
LVS +Keepalived 高可用群集部署
一、LVSKeepalived 高可用群集 在这个高度信息化的 IT 时代,企业的生产系统、业务运营、销售和支持,以及日常管理等环节越来越依赖于计算机信息和服务,对高可用(HA)技术的应用需求不断提高,以便提供持续的…...
Kafka调优
生产者 参数名称描述bootstrap.serverskafka集群的地址key.deserializerkey的反序列化类,写全类名value.deserializervalue的反序列化类,写全类名buffer.memoryRecordAccumulator缓冲区总大小,默认32mbatch.size缓冲区一批数据最大值&#x…...
Debezium系列之:详细介绍Debezium2.X版本导出Sqlserver数据库Debezium JMX指标的方法
Debezium系列之:详细介绍Debezium2.X版本导出Sqlserver数据库Debezium JMX指标的方法 一、需求背景二、相关技术文章三、安装jmx_prometheus_javaagent四、Debezium2.X版本Sqlserver数据库jmx指标格式五、导出Debezium2.X版本Sqlserver数据库jmx指标方法六、Debezium2.X版本各…...
基于PWM技术的三相光伏逆变器研究(Simulink)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
〖Python网络爬虫实战㉑〗- 数据存储之JSON操作
订阅:新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列(零基础小白搬砖逆袭) 说明:本专栏持续更新中,目前专栏免费订阅,在转为付费专栏前订阅本专栏的,可以免费订阅付…...
不得不说的行为型模式-责任链模式
目录 责任链模式: 底层原理: 代码案例: 下面是面试中可能遇到的问题: 责任链模式: 责任链模式是一种行为型设计模式,它允许多个对象在一个请求序列中依次处理该请求,直到其中一个对象能够…...
基于dsp+fpga+AD+ENDAC的半导体运动台高速数据采集电路仿真设计(四)
整个调试验证与仿真分析分三个步骤:第一步是进行 PCB 检查及电气特性测试,主 要用来验证硬件设计是否正常工作;第二步进行各子模块功能测试,包括高速光纤串行 通信的稳定性与可靠性测试, A/D 及 D/A 转换特性测…...
快速搭建Electron+Vite3+Vue3+TypeScript5脚手架 (无需梯子,快速安装Electron)
一、介绍 😆 😁 😉 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需…...
语义分割学习笔记(二)转置卷积
目录 1.转置卷积Transposed Convolution概念 2.转置卷积操作步骤 3.转置卷积参数 4.实战案例 推荐课程:转置卷积(transposed convolution)_哔哩哔哩_bilibili 感谢霹雳吧啦Wz,真乃神人也。 1.转置卷积Transposed Convolutio…...
docker运行PostgreSQL数据库维护,执行脚本备份数据库与更新表结构
文章目录 PostgreSQL简介业务场景数据库维护docker-compose配置备份脚本更新表结构脚本 PostgreSQL简介 PostgreSQL是一种开源的关系型数据库管理系统,它是一个功能强大、高度可定制化和支持复杂应用的数据库。它支持广泛的数据类型,包括数值、文字、二…...
【计算机网络】127.0.0.1、0.0.0.0、localhost地址是什么?
目录 0.0.0.0是什么?127.0.0.1是什么?用途 localhost是什么?总结 0.0.0.0是什么? IPV4中,0.0.0.0地址被用于表示一个无效的,未知的或者不可用的目标。 在服务器中,0.0.0.0指的是本机上的所有I…...
分享2款CSS3母亲节主题寄语文字动画特效
目录 ❤️ 前言 第一款:妈妈您辛苦了! 一、效果图 二、代码实现 第二款:Mothers Day! 一、效果图 二、代码实现 ❤️ 祝福 ❤️ 前言 母亲节,在每年五月的第二个星期日,是用来感谢母亲的节日。…...
【AutoGPT】AutoGPT出现,是否意味着ChatGPT已被淘汰
Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员,2024届电子信息研究生 目录 前言 什么是ChatGPT? 什么是AutoGPT? AutoGPT与ChatGPT的区别 AutoGPT的优势和劣势 优势 劣势 ChatGPT是否会被淘汰? 前言 近年来&#x…...
网站建设联系电话/谷歌推广效果好吗
django ORM model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct1.多表连接查询:感觉django太NX了。class A(models.Model):name models.CharField(u名称)class B(models.Model):aa models.ForeignKey(A)B.objects.filter(aa…...
建设网站用什么app/宁波seo博客
近日在使用SQL Server 2008 Management Studio时遇到一个奇怪的问题,之前的数据库是用SQL Server 2005创建的,我将数据库文件复制到另外一台机器上,这台机器上安装的是SQL Server 2008,将数据库文件附加进来没有任何问题ÿ…...
建站网站/北京网站外包
a.如果备份的数据库可以访问,那么执行执行生产转化脚本:select set newname for datafile || file# || to ||replace( name,/old/data/path,/new/data/path ) || ; from v$datafile;b.如果备份的数据库不可以访问,可以trace控制文件内容&a…...
最好的营销型网站建设公司/南宁网站seo优化公司
初学JDBC,看了看书,自己动手的时候还是有很多地方有问题,最终终于解决了实现了数据库的连接。现将整个步骤描述如下:环境:mySQL5.1.26(win 32bit), Eclipse JavaEE IDE1mySQL的安装:最新版本是5.1.26&#…...
wordpress 网站锁/网站建网站建设网站
本文实例讲述了jQuery超简单遮罩层实现方法。共享给大家供大家参考,详细如下:在开发中,为了避免二次提交,遮罩层的运用越来越普遍看了很多代码,下面跟大家共享一下我认为最简单的遮罩层实现方式:1.风格如下…...
装修案例/搜索引擎优化的英文
开启redis-server提示 # Creating Server TCP listening socket *:6379: bind: Address already in use--解决方法参考文章: (1)开启redis-server提示 # Creating Server TCP listening socket *:6379: bind: Address already in use--解决方…...