当前位置: 首页 > news >正文

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中&#xff0c;经常用到的ovs命令&#xff0c;参数&#xff0c;与举例总结&#xff0c;持续更新中… 进程启动 1.先准备ovs的工作目录&#xff0c;数据库存储路径等 mkdir -p /etc/openvswitch mkdir -p /var/run/openvswitch …...

一以贯之:从城市网络到“城市一张网”

《论语里仁》中子曰&#xff1a;“参乎&#xff0c;吾道一以贯之”。 孔子所说的“一以贯之”&#xff0c;逐渐成为了中国文化与哲学的重要组成部分&#xff0c;指明事物发展往往需要以标准化、集约化、融合化作为目标。这种智慧在数字化发展中格外重要。从云计算、大数据技术模…...

【Java校招面试】基础知识(四)——JVM

目录 前言一、基础概念二、反射三、类加载器ClassLoader四、JVM内存模型后记 前言 本篇主要介绍Java虚拟机——JVM的相关内容。 “基础知识”是本专栏的第一个部分&#xff0c;本篇博文是第四篇博文&#xff0c;如有需要&#xff0c;可&#xff1a; 点击这里&#xff0c;返回…...

项目管理-计算专题(三点估算、PERT估算)

基本概念 通过考虑估算中的不确定性和风险&#xff0c;可以提高活动持续时间估算的准确性。这个概念源自计划评审技术(PERT)。PERT使用三种估算值来界定活动持续时间的近似区间: 最可能时间(tM)&#xff1a;基于最可能获得的资源、最可能取得的资源生产率、对资源可用时间的现…...

【华为OD机试 2023最新 】模拟商场优惠打折(C语言题解 100%)

文章目录 题目描述输入描述输出描述用例题目解析代码思路C语言题目描述 模拟商场优惠打折,有三种优惠券可以用,满减券、打折券和无门槛券。 满减券:满100减10,满200减20,满300减30,满400减40,以此类推不限制使用; 打折券:固定折扣92折,且打折之后向下取整,每次购…...

使用TrieTree(字典树)来实现敏感词过滤

使用TrieTree&#xff08;字典树&#xff09;来实现敏感词过滤 1. 字典树定义 字典树&#xff08;TrieTree&#xff09;&#xff0c;是一种树形结构&#xff0c;典型应用是用于统计&#xff0c;排序和保存大量的字符串&#xff08;但不仅限于字符串,如01字典树&#xff09;。…...

USB转串口芯片CH9101U

CH9101是一个USB总线的转接芯片&#xff0c;实现USB转异步串口。提供了常用的MODEM联络信号&#xff0c;用于为计算机扩展异步串口&#xff0c;或者将普通的串口设备或者MCU直接升级到USB总线。 特点 全速USB设备接口&#xff0c;兼容USB V2.0。内置固件&#xff0c;仿真标准串…...

Java语言介绍

Java是一种广泛使用的计算机编程语言&#xff0c;由Sun Microsystems公司于1995年推出。它是一个健壮的、面向对象的、跨平台的语言&#xff0c;被用于开发各种应用程序和系统&#xff0c;包括Web应用程序、移动应用程序、桌面应用程序、游戏以及企业级系统等。 Java具有许多优…...

终于把 vue-router 运行原理讲明白了(二)!!!

一、vue-router路由变化侦测 1.1 上一遍文章中&#xff0c;介绍了vue-router 的install 函数的内部实现&#xff0c;知道了能在this中访问$router 和视图更新的机制&#xff0c;文章链接终于把 vue-router 运行原理讲明白了&#xff08;一&#xff09;&#xff01;&#xff01…...

ChatGPT实现服务器体验沙箱

服务器体验沙箱 IT 人员在学习一门新技术时&#xff0c;第一个入门门槛通常都是"如何在本地安装并成功运行"。因此&#xff0c;很多技术的官网都会通过沙箱技术&#xff0c;提供在线试用的 playground 或者按步模拟的 tour。让爱好者先在线尝试效果是否满足预期&…...

【算法】刷题中的位运算

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;人类做题的过程&#xff0c;其实是暴搜的过程&#x1f43e; 文章目录 1.位运算概述2.位运算符3.位运算应用3.1整数的奇偶性判断3.2有关 2 的幂的应用3.3lowbit(x)返回x的最后一位13.4二进制数中1的个数3.5求…...

9.Java中异常处理机制是什么

Java的异常处理通过五个关键字来实现&#xff0c;分别是捕获异常&#xff1a;try&#xff0c;catchsfinally&#xff1b;声明异常&#xff1a;throws&#xff1b;抛出异常&#xff1a;throw 一&#xff1a;try&#xff0c;catch捕获异常二&#xff1a;finally回收资源三&#x…...

GeoTools实战指南: 叠加GeoTIFF与Shapefile图层生成截图

GeoTools实战指南: 叠加GeoTIFF与Shapefile图层生成截图 介绍 本教程将介绍如何使用GeoTools库在Java中将栅格数据(GeoTIFF)与矢量数据(Shapefile)叠加显示,并将结果保存为PNG格式的图片文件。我们将解析和分析 RasterDataRenderer 类,并了解其中的每个方法和对象。 准…...

nginx配置sh脚本远程执行一键安装

背景 本地多机重复操作某些shell指令&#xff0c;分步执行&#xff0c;很耗费时间&#xff0c; 需要远程一键部署&#xff0c;傻瓜化运维&#xff0c;更为通用安装。 即参考docker通用安装 sudo curl https://get.docker.com | sh - # sudo python3 -m pip install docker-co…...

Excel表格成绩排名全攻略,让你事半功倍!

在学校或公司中&#xff0c;我们经常需要对成绩进行排名。如果手动计算排名&#xff0c;不仅费时费力&#xff0c;而且容易出错。幸运的是&#xff0c;Microsoft Excel提供了一个简单而快速的方法来计算和显示排名。 在学校或公司中&#xff0c;成绩排名是一项重要的任务。使用…...

Docker 持久化存储 Bind mounts

Docker 持久化存储 Bind mounts Bind mounts 的 -v 与 --mount 区别启动容器基于bind mount挂载到容器中的非空目录只读 bind mountcompose 中使用 bind mount 官方文档&#xff1a;https://docs.docker.com/storage/bind-mounts/ Bind mounts 的 -v 与 --mount 区别 如果使用…...

LVS +Keepalived 高可用群集部署

一、LVSKeepalived 高可用群集 在这个高度信息化的 IT 时代&#xff0c;企业的生产系统、业务运营、销售和支持&#xff0c;以及日常管理等环节越来越依赖于计算机信息和服务&#xff0c;对高可用&#xff08;HA&#xff09;技术的应用需求不断提高&#xff0c;以便提供持续的…...

Kafka调优

生产者 参数名称描述bootstrap.serverskafka集群的地址key.deserializerkey的反序列化类&#xff0c;写全类名value.deserializervalue的反序列化类&#xff0c;写全类名buffer.memoryRecordAccumulator缓冲区总大小&#xff0c;默认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)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

〖Python网络爬虫实战㉑〗- 数据存储之JSON操作

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…...

不得不说的行为型模式-责任链模式

目录 责任链模式&#xff1a; 底层原理&#xff1a; 代码案例&#xff1a; 下面是面试中可能遇到的问题&#xff1a; 责任链模式&#xff1a; 责任链模式是一种行为型设计模式&#xff0c;它允许多个对象在一个请求序列中依次处理该请求&#xff0c;直到其中一个对象能够…...

基于dsp+fpga+AD+ENDAC的半导体运动台高速数据采集电路仿真设计(四)

整个调试验证与仿真分析分三个步骤&#xff1a;第一步是进行 PCB 检查及电气特性测试&#xff0c;主 要用来验证硬件设计是否正常工作&#xff1b;第二步进行各子模块功能测试&#xff0c;包括高速光纤串行 通信的稳定性与可靠性测试&#xff0c; A/D 及 D/A 转换特性测…...

快速搭建Electron+Vite3+Vue3+TypeScript5脚手架 (无需梯子,快速安装Electron)

一、介绍 &#x1f606; &#x1f601; &#x1f609; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需…...

语义分割学习笔记(二)转置卷积

目录 1.转置卷积Transposed Convolution概念 2.转置卷积操作步骤 3.转置卷积参数 4.实战案例 推荐课程&#xff1a;转置卷积&#xff08;transposed convolution&#xff09;_哔哩哔哩_bilibili 感谢霹雳吧啦Wz&#xff0c;真乃神人也。 1.转置卷积Transposed Convolutio…...

docker运行PostgreSQL数据库维护,执行脚本备份数据库与更新表结构

文章目录 PostgreSQL简介业务场景数据库维护docker-compose配置备份脚本更新表结构脚本 PostgreSQL简介 PostgreSQL是一种开源的关系型数据库管理系统&#xff0c;它是一个功能强大、高度可定制化和支持复杂应用的数据库。它支持广泛的数据类型&#xff0c;包括数值、文字、二…...

【计算机网络】127.0.0.1、0.0.0.0、localhost地址是什么?

目录 0.0.0.0是什么&#xff1f;127.0.0.1是什么&#xff1f;用途 localhost是什么&#xff1f;总结 0.0.0.0是什么&#xff1f; IPV4中&#xff0c;0.0.0.0地址被用于表示一个无效的&#xff0c;未知的或者不可用的目标。 在服务器中&#xff0c;0.0.0.0指的是本机上的所有I…...

分享2款CSS3母亲节主题寄语文字动画特效

目录 ❤️ 前言 第一款&#xff1a;妈妈您辛苦了&#xff01; 一、效果图 二、代码实现 第二款&#xff1a;Mothers Day&#xff01; 一、效果图 二、代码实现 ❤️ 祝福 ❤️ 前言 母亲节&#xff0c;在每年五月的第二个星期日&#xff0c;是用来感谢母亲的节日。…...

【AutoGPT】AutoGPT出现,是否意味着ChatGPT已被淘汰

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 前言 什么是ChatGPT&#xff1f; 什么是AutoGPT&#xff1f; AutoGPT与ChatGPT的区别 AutoGPT的优势和劣势 优势 劣势 ChatGPT是否会被淘汰&#xff1f; 前言 近年来&#x…...

网站建设联系电话/谷歌推广效果好吗

django ORM model filter 条件过滤&#xff0c;及多表连接查询、反向查询&#xff0c;某字段的distinct1.多表连接查询&#xff1a;感觉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时遇到一个奇怪的问题&#xff0c;之前的数据库是用SQL Server 2005创建的&#xff0c;我将数据库文件复制到另外一台机器上&#xff0c;这台机器上安装的是SQL Server 2008&#xff0c;将数据库文件附加进来没有任何问题&#xff…...

建站网站/北京网站外包

a.如果备份的数据库可以访问&#xff0c;那么执行执行生产转化脚本&#xff1a;select set newname for datafile || file# || to ||replace( name,/old/data/path,/new/data/path ) || ; from v$datafile;b.如果备份的数据库不可以访问&#xff0c;可以trace控制文件内容&a…...

最好的营销型网站建设公司/南宁网站seo优化公司

初学JDBC&#xff0c;看了看书&#xff0c;自己动手的时候还是有很多地方有问题&#xff0c;最终终于解决了实现了数据库的连接。现将整个步骤描述如下&#xff1a;环境&#xff1a;mySQL5.1.26(win 32bit), Eclipse JavaEE IDE1mySQL的安装&#xff1a;最新版本是5.1.26&#…...

wordpress 网站锁/网站建网站建设网站

本文实例讲述了jQuery超简单遮罩层实现方法。共享给大家供大家参考&#xff0c;详细如下&#xff1a;在开发中&#xff0c;为了避免二次提交&#xff0c;遮罩层的运用越来越普遍看了很多代码&#xff0c;下面跟大家共享一下我认为最简单的遮罩层实现方式&#xff1a;1.风格如下…...

装修案例/搜索引擎优化的英文

开启redis-server提示 # Creating Server TCP listening socket *:6379: bind: Address already in use--解决方法参考文章&#xff1a; &#xff08;1&#xff09;开启redis-server提示 # Creating Server TCP listening socket *:6379: bind: Address already in use--解决方…...