Redis源码篇- SDS

news2025/3/10 9:53:08

Redis对于String类型,底层使用的是SDS(简单动态字符串),而不是常规的C语言的字符数组 。

通常在C中,定义一个字符串,方式是通过字符数组表示,同时结尾使用/0表示结束:char [] = "hello,world/0";
计算字符串长度则为:遍历char[],复杂度O(n) ;  

常规的C中字符串使用带来的问题:

  • 获取长度复杂度为O(n),Redis在万+的处理时,会收到一定性能影响
  • 常规字符串读取,遇到"/0"会自动结束,对于Redis来说是二进制不安全的,因为可能存在String类型values就是存在\0的内存,此时就会被错误截断,这也是二进制不安全
  • 同时当需要对字符串进行修改时,需要重新分配空间,否则会有缓存区溢出或者内存泄漏的风险。

SDS是基于C字符串之上的一种封装,用来解决C字符串的缺陷问题,这种封装的特殊的数据结构就是SDS。

数据结构:sdshdr5

sdshdr8

 SDS数据结构体名称sdshdr,分为5、8、16、32、64 5种,根据数据内容大小自动选择适合SDS结构存储,节省空间。

sdshdr 和 sds是什么关系?
  SDS是一个字符数组指针,指向了sdshdr种buf[] , 所以可以理解为SDS就是字符数组,但是可以通过SDS获取到
sdshdr中len等相关信息(通过指针位数的计算,获取)

 Redis为什么使用SDS,高效?

1、高效获取字符串长度,复杂度O(1)

常规的C字符串长度获取,需要遍历Char数组,复杂度O(n),SDS中可以通过,指针的移动获取到len等内容,复杂度O(1) ; 比如多次使用strlen指令会提高效率,记住Redis是将面临万+的请求处理的,所以该提效是非常有用的。

2、减少内存重新分配次数,即减少内核调用

常规C字符串中,对内容进行修改,需要重新分配内存大小 ,比如ABC存储时,分配大小为3字节:

  •      如果新增内容时,需要重新进行内存分配,否则会缓冲区溢出。
  •       如果减少内容时,也需要重新进行内存分配,否则会有内存溢出风险

SDS结构体系中,存有当前总申请空间大小alloc 和使用空间大小use , 于是就能得出free空间大小(在版本redis就是存有free属性);SDS就是通过free实现了
空间预分配惰性空间释放两种优化。 

· 空间预分配

用于添加字符串内容时
 : 此机制有点像java中list内存分配了 。
大致策略 : 当SDS需要更多内存分配时,不久分配需要的空间,也会分配更多的free空间,这样下一次append内容时,就不会在重新分配空间,当再一次需要分配空间时,依然会多分配空间。(当newlen< 1mb,则free分配 = len大小 , 当newlen >=1mb,则分配free = 1bm)

· 惰性空间释放
用于缩短字符串内容时

大致策略 : 当SDS需要缩短字符串内容时,不会立马释放多余空间,而是将多余的空间大小记录到free中,以供下次使用。(当达到某种条件时-free > 10% * len
,通过客户端操作触发,再去释放多余空间 -- 惰性

 3、二进制安全

c字符串中的字符必须符合某种编码(ASCII),不能保存图片,音频等这样的二进制数据在读取时必须按照格式进行读取。
SDS是通过len来决定截取字符数组的内容的,而不是像常规 C字符串通过/0 ,来截取,所以SDS保留了完整的字符串内容,所以是二进制安全的。

4、节省空间

Redis使用SDS会根据内容大小,使用不同结构的SDS,比如sdshrd5、8、16等,不同结构体空间大小不同,对于小的字符数组内容就是用小SDS结构,节省空间。

地址:

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

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

相关文章

C语言 与 C++ 通讯录对比实现(附带源码)

目录 1.通讯录的基本框架 C语言版 C版 2.增加联系人 C语言版 C版 3.删除联系人 C语言版 C版 4.查找与打印联系人 C语言版 C版 5.修改联系人 C语言版 C版 6.排序联系人 C语言版 C版 7.其他 8.总结 本文章将对C语言、C版本的通讯录进行对比实现。其中C版本引入大量C语言没有的特性…

第 5 章 Spark Shuffle 解析

第 5 章 Spark Shuffle 解析 5.1 Shuffle 的核心要点1. 数据分区&#xff1a;2.数据传输&#xff1a;3. 数据排序&#xff1a;4.数据聚合&#xff1a;5. 数据重分发&#xff1a;6.数据持久化&#xff1a;5.1.1 ShuffleMapStage 与 ResultStage 5.2 HashShuffle 解析5.2.1 未优化…

KUKA机器人_外部安全条件不满足时,如何操作机器人的方法

KUKA机器人_外部安全条件不满足时&#xff0c;如何操作机器人的方法 如果大家在做项目时&#xff0c;控制系统尚未完成&#xff0c;外部紧急停止等安全条件尚未满足时&#xff0c;但是此时想操作或移动机器人&#xff0c;有办法吗&#xff1f; 答案是有。 具体的方法可参考以…

驾驶证——科目一笔记(二)

知识点1&#xff1a;通行规定 有加速&#xff08;x&#xff09; 各种礼让&#xff08;√&#xff09; 减速慢行、减速靠右、减速或停车、停车避让&#xff08;√&#xff09; 不用减速慢行、无需减速、不必减速&#xff08;x&#xff09; 不得&#xff08;√&#xff09; …

【文档模板】产品故障分析报告

今天和大家分享产品故障分析报告的文档模板。产品故障分析报告是一份文件&#xff0c;通常由技术团队、工程师或相关专业人员编写&#xff0c;用于详细描述和分析出现在系统、设备、产品或服务中的故障原因和根本原因。这些报告旨在对故障进行系统性的研究&#xff0c;以便团队…

Windows沙盒的安装与配置

沙盒安装 1、打开控制面板 2、选择程序与功能 3、勾选Windows 沙盒&#xff0c;然后点击确定&#xff0c;等待安装完成即可。 沙盒配置 Windows 沙盒支持简单的配置文件&#xff0c;这些文件为沙盒提供最少的自定义参数集。 此功能可与 Windows 10 内部版本 18342 或 Windows…

数据库管理-第九十二期 一周故障汇总(20230717)

第九十二期 一周故障汇总&#xff08;20230717&#xff09; 距离上一篇已经过了整整一周了&#xff0c;平时我虽然不是生产队的驴&#xff0c;但是一周一篇以上的数量还是维持了一段时间了。为啥上周只写了一篇&#xff0c;因为各种故障、各种保障、各种割接忙了整整一周&…

数据分析师:解读数据背后的故事

数据在当今信息时代中扮演着至关重要的角色&#xff0c;而数据分析师则是解读和发掘数据中隐藏信息的关键人物。作为数据分析师&#xff0c;他们运用统计学、机器学习和数据可视化等技术手段&#xff0c;从海量的数据中提取出有价值的信息和洞察&#xff0c;并将其转化为可供决…

大数据学习02-Hadoop分布式集群部署

操作系统&#xff1a;centos7 软件环境&#xff1a;jdk8、hadoop-2.8.5 一、创建虚拟机 1.下载VMware,建议支持正版 2.安装到Widows目录下任意位置即可&#xff0c;安装目录自定义。打开VMware&#xff0c;界面如下&#xff1a; 3.创建虚拟机 创建虚拟机—>选择自定义 …

kafka消息队列最常用的两种模式,以及应用场景

目录 一、发布-订阅模式 二、点对点模式 三、应用场景 一、发布-订阅模式 发布-订阅模式是最常见的消息传递模式&#xff0c;其中消息发布者将消息发送到一个或多个主题&#xff08;Topic&#xff09;&#xff0c;而订阅者可以选择订阅一个或多个主题来接收消息。每个订阅者…

在嵌入式系统开发培训中常用的数据库有哪些种?

数据库是一种储存和管理、组织数据的仓库&#xff0c;在嵌入式开发当中起到至关重要的作用。一个在嵌入式培训中&#xff0c;我们可学习使用的数据库有多种&#xff0c;每种数据库都会呈现出不同的一面&#xff0c;那么我们在嵌入式系统开发培训中可用到的数据库都有哪几种&…

JQuery(二):DOM操作、动画、遍历、事件绑定

1.DOM操作 1.1内容操作 html(): 获取/设置元素的标签体内容 <a><font>内容</font></a> --> <font>内容</font>text(): 获取/设置元素的标签体纯文本内容 <a><font>内容</font></a> --> 内容val()&am…

RK3588+FPGA视频实时处理与双屏显示、存储解决方案

主板平台的主要功能电路示意图 在ARM端: 脚踏开关是电平输入10 口&#xff0c;双路。 触摸面板与主板的连接方式为 UART 外加12V 电源。 键盘为自开发产品&#xff0c;通过USB透传 UART&#xff0c;并传递12V电源USB、千兆网络为主板上的接口&#xff0c;USB 为3.0版本host 接口…

Hadoop 之 单机部署和测试(一)

Hadoop单机部署和测试 一.单机部署1.安装 JDK&#xff08;JDK11&#xff09;2.安装 HADOOP3.测试 一.单机部署 系统版本&#xff1a;cat /etc/anolis-release1.安装 JDK&#xff08;JDK11&#xff09; #!/bin/bashTOP_PATH$(pwd) JAVA_PATH/usr/local/java FILEls $TOP_PATH/…

【Linux | Shell】结构化命令2 - test命令、方括号测试条件、case命令

目录 一、概述二、test 命令2.1 test 命令2.2 方括号测试条件2.3 test 命令和测试条件可以判断的 3 类条件2.3.1 数值比较2.3.2 字符串比较 三、复合条件测试四、if-then 的高级特性五、case 命令 一、概述 上篇文章介绍了 if 语句相关知识。但 if 语句只能执行命令&#xff0c…

兴达易控modbus转profinet网关与三菱变频器通讯

本案例分享兴达易控modbus转profinet网关&#xff08;MDPN100&#xff09;连接西门子1200plc&#xff0c;实现三菱变频器485通讯兼容转modbusTCP通信&#xff0c;在博图中配置。 拓展图 打开博图&#xff0c;并添加PLC 加载由兴达易控免费提供的modbus转profinet GSD文件 安装网…

基于MSP432P401R送药小车【2021年电赛F题】

文章目录 一、任务清单1. 硬件部分2. 软件部分 二、神经网络训练1. 创建数据集2. 数据采集3. 数字训练 三、OpenMV数字及其坐标识别四、巡线1. 直行2. 转向3. 停止 五、路口判断与原路径返回六、技术交流 由于前边已经用MSP430做过一遍该赛题了&#xff0c;这里就不再重复叙述赛…

Java培训:什么是Busy spin?为什么要使用Busy spin?

Busy spin(繁忙自旋)是一种线程等待的技术&#xff0c;它通过循环检查条件来等待某个事件或条件的发生&#xff0c;而不进行阻塞或休眠。 通常情况下&#xff0c;线程等待事件发生的方式是使用阻塞或休眠操作&#xff0c;这样线程会释放CPU资源&#xff0c;其他线程可以继续执行…

Qt6 Qt Quick UI原型学习QML第二篇

Qt6 Qt Quick UI原型学习QML第二篇 界面效果QML语法语法讲解核心要素项目元素矩形元素文本元素图像元素MouseArea元素 界面效果 QML语法 import QtQuick 2.12 import QtQuick.Window 2.12Window {id: rootvisible: truewidth: 640height: 480title: qsTr("QML学习第二篇&…

【题解】 模拟赛2 题解

T1 假设商品价格为x 618:int(x*0.66) 211:x-(x/100)*35 两者比较一下大小即可 #include<bits/stdc.h> using namespace std;int x,x1,x2;int main(){scanf("%d",&x);x1 x*0.66;x2 x-(x/100)*35;if (x1 x2) printf("both\n%d",x1);if (x1 &g…