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

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.rhkb.cn/news/159236.html

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

相关文章

Master PDF Editor v5.9.70便携版

软件介绍 Master PDF Editor中文版是一款小巧的多功能PDF编辑器,可以轻松查看,创建,修改,批注,签名,扫描,OCR和打印PDF文档.高级注释工具,可以添加任意便笺指示对象突出显示,添加下划线和删除,而无需更改源PDF文件. 软件截图 更新日志 code-industry.net/what-is-new-in-mas…

4.1 继承性

知识回顾 (1)类和对象的理解? 对象是现实世界中的一个实体,如一个人、一辆汽车。一个对象一般具有两方面的特征,状态和行为。状态用来描述对象的静态特征,行为用来描述对象的动态特征。 类是具有相似特征…

goland 旧版本使用1.19环境

C:\Go\src\runtime\internal\sys\zversion.go // Code generated by go tool dist; DO NOT EDIT.package sysconst StackGuardMultiplierDefault 1const TheVersion go1.19引入其他包的标识符 package mainimport ("fmt""gotest/test")func main() {f…

Flask (Jinja2) 服务端模板注入漏洞复现

文章目录 Flask (Jinja2) 服务端模板注入漏洞1.1 漏洞描述1.2 漏洞原理1.3 漏洞危害1.4 漏洞复现1.4.1 漏洞利用 1.5 漏洞防御 Flask (Jinja2) 服务端模板注入漏洞 1.1 漏洞描述 说明内容漏洞编号漏洞名称Flask (Jinja2) 服务端模板注入漏洞漏洞评级高危影响版本使用Flask框架…

Linux友人帐之调试器--gdb的使用

一、debug和realease版本的区别 区别 debug是给程序员用的版本,添加了调试信息,用于解决软件或程序中出现的问题,realease是发行给客户使用的版本,并未添加调试信息,只需要给客户提供优越的产品使用环境即可&#xff…

数据库系统概论学习 1 绪论

1.1.1 数据、数据库、数据库管理系统、数据库系统 一、数据 Data 数据是数据库中存储的基本对象 定义:描述事物的符号记录称为数据,描述事物的符号可以是数字、文字、图像、图形、声音、语言等表现形式,它们都可以经过数字化后存入计算机。…

【C++进阶】:C++类型转换

C类型转换 一.C语言里的类型转换二.C语音类型转换的一些弊端三.C的四种类型转换1.static_cast2.reinterpret_cast3.const_cast4.dynamic_cast 一.C语言里的类型转换 在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者…

ST‐LINK V2 使用说明(安装,调试,烧录)

目录 1. 初识 ST-LINK V2 1.1 ST-LINK V2 简介 2. ST-LINK V2 驱动的安装与固件升级 2.1 驱动的安装 2.2 固件的升级 3. 使用 STM32 ST-LINK Utility 烧写目标板 hex 3.1 ST-LINK 烧写 hex 文件 4.使用 ST-LINK V2 调试 STM8 4.1 ST‐LINK 调试 STM8 5.…

String方法:分割、梦回C语言,格式化输出format

String poem "锄禾日当午&#xff0c;汗滴禾下土&#xff0c;谁知盘中餐&#xff0c;粒粒皆辛苦";String[] split poem.split("&#xff0c;");System.out.println("悯农");for (int i 0; i < split.length; i) {System.out.println(split…

53 打家劫舍

打家劫舍 题解1 DP1题解2 DP2 &#xff01;经典DP&#xff01; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果 两间相邻的房屋在同一晚上被小偷闯入…

【C++】继承 -- 详解

一、继承的概念及定义 1、继承的概念 继承 (inheritance) 机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保 持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。 继承呈现了面向对象 程序设…

【Vue】vue2与netcore webapi跨越问题解决

系列文章 C#底层库–记录日志帮助类 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/124187709 文章目录 系列文章前言一、技术介绍二、问题描述三、问题解决3.1 方法一&#xff1a;前端Vue修改3.2 方法二&#xff1a;后端允许Cors跨越访问 四、资源…

前端TypeScript学习day04-交叉类型与泛型

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 交叉类型 泛型 创建泛型函数 调用泛型函数&#xff1a; 简化调用泛型函数&#xff1a; 泛型约束 指定…

浅谈MDK, IAR,CLANG和GCC的局部变量字节对齐处理差异(2023-10-13)

视频&#xff1a; https://www.bilibili.com/video/BV1CB4y1Z7kA 浅谈MDK, IAR, CLANG和GCC的局部变量字节对齐处理差异 问题由来&#xff1a; 早期这个帖子里面的局部变量对齐仅测试了MDK AC5&#xff0c;但项目中使用AC6发现了新问题&#xff0c;看来AAPCS规约研究的还是不…

centos 里面的service自启动app.jar,出现两个java进程,app是同一个端口

当使用jps -lv查看java虚拟机进程 app.jar启动后&#xff0c;居然出现两个启动进程&#xff0c;而且他们的端口都一样&#xff0c;同一端口&#xff0c;是不允许启动两个相同app的。 使用进程ps查看进程工具 #ps -aux 参数说明&#xff1a; a: 显示跟当前终端关联的所有进…

《Deep Residual Learning for Image Recognition》阅读笔记

论文标题 《Deep Residual Learning for Image Recognition》 撑起CV界半边天的论文Residual &#xff1a;主要思想&#xff0c;残差。 作者 何恺明&#xff0c;超级大佬。微软亚研院属实是人才辈出的地方。 初读 摘要 提问题&#xff1a; 更深层次的神经网络更难训练。 …

PHP基础语法(上)

目录 前言 一、基础语法 1.1 标记 1.2 输出语句 1.2.1 echo 1.2.2 print 1.3 注释 1.3.1 单行注释 1.3.2 多行注释 1.4 标识符 1.5 关键字 二、数据与运算 2.1 常量 2.1.1 常量的定义和使用 2.1.2 预定义常量 2.2 变量 2.2.1 变量的赋值 2.2.2 超全局变量 2.3 数据类型 2.3.1 …

Nginx:反向代理(示意图+配置)

示意图&#xff1a; 反向代理 反向代理&#xff08;Reverse Proxy&#xff09;是代理服务器的一种&#xff0c;它代表服务器接收客户端的请求&#xff0c;并将这些请求转发到适当的服务器。当请求在后端服务器完成之后&#xff0c;反向代理搜集请求的响应并将其传输给客户端。…

Tableau:商业智能(BI)工具

Tableau入门 1、Tableau概述2、Tableau Desktop2.1、初识Tableau Desktop2.2、Tableau工作区2.3、数据窗格与分析窗格2.4、功能区和标记卡2.4.1、列和行功能区2.4.2、标记卡2.4.3、筛选器功能区2.4.4、页面功能区2.4.5、附加功能区、图例、控件 3、Tableau视图4、Tableau工作簿…

LeetCode讲解篇之198. 打家劫舍

LeetCode讲解篇之198. 打家劫舍 文章目录 LeetCode讲解篇之198. 打家劫舍题目描述题解思路题解代码 题目描述 题解思路 该问题可以通过递推来完成 递推公式&#xff1a; 前n间房的最大金额 max&#xff08;前n-1间房的最大金额&#xff0c; 前n-2间房的最大金额第n-1间房的最…