Redis-SDS

news2024/11/24 10:37:34

本文你能得到:

1 SDS基本介绍 。

2 SDS与 C语言传统字符串的区别,为什么使用SDS。

3 SDS的结构和策略详解。

1 SDS 是什么?用来做什么?

1.1 ​ Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组),而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。

1.2 在Redis的数据库里面,包含字符串值的键值对在底层都 是由SDS实现的。

2 SDS结构:

2.1类

struct sdshdr {
    //记录buf数组中已使用字节的数量
    //等于SDS所保存字符串的长度
    int len;
    //记录buf数组中未使用字节的数量
    int free;
    //字节数组,用于保存字符串
    char buf[];
};

2.2图

 2.3 讲解

free 用于存储buf数组 剩余可用空间

len用于存储已用空间

buf 字节数组用于存储内容

2.4 问题

为什么数组最后 '\0' 空结尾?

请看3.1

3 char数组介绍的缺点

3.1 char 介绍

char 数组在 写入时候会分配内存 ,比如写入 Redis 就会分配6个存储空间,如图

这样在char读取的时候,首先会根据 内存指针找到开头的R 然后到 \0 结束,如果么有\0 char就不知道什么时候结束,但为啥SDS也要这样呢,因为能复用string.h等对字符串操作的工具类。 

缺点1 缓冲区溢出。

举例当两个char <string.h>/strcat函数可以将src字符串中的内容拼接到dest字符串的末尾:

char *strcat(char *dest, const char *src);

如果dest没有分配足够的内存空间,就会导致超出 dest 内存空间的部分 被写上src的数据,超出的部分可能分配给了其他变量,所以会导致其他变量数据错误,缓冲区溢出。

缺点2 内存泄漏

如果通过函数 删除了char数组中的一些数据,如果么有重新分类空间,会导致内存泄漏,删除的部分将不会被使用。

缺点3 重新分配地址

所以每次操作char都需要重新分配内存空间,来解决字符增加导致的缓冲区溢出,和减少字符串导致的内存泄漏,这样每次分配内存就有很大的成本,不适合redis这么频繁的操作。

缺点4 获取数组长度时间复杂度O(N)

如果要获取字符产股 需要循环每一个字符计数,时间复杂度O(N)) 而 SDS只需要返回len就可以时间复杂度O(1)

总结:

1 如果程序执行的是增长字符串的操作,比如拼接操作(append),那么在执行这个操作之前,程序需要先通过内存重分配来扩展底层数组的空间大小——如果忘了这一步就会产生缓冲区溢出。

2 如果程序执行的是缩短字符串的操作,比如截断操作(trim),那么在执行这个操作之后,程序需要通过内存重分配来释放字符串不再使用的那部分空间——如果忘了这一步就会产生内存泄漏。

4 SDS如何解决内存以上问题

4.1 空间预分配解决缓冲区溢出问题,避免频繁分配内存,代价是多一些有可能不会被使用到的空间浪费。

策略1

如果对SDS进行修改之后,SDS的长度(也即是len属性的值)将小于1MB,那么程序分配和len属性同样大小的未使用空间,这时SDS len属性的值将和free属性的值相同。举个例子,如果进行修改之后,SDS的len将变成13字节,那么程序也会分配13字节的未使用空间,SDS的buf数组的实际长度将变成13+13+1=27字节(额外的一字节用于保存空字符)。

策略 2

如果对SDS进行修改之后,SDS的长度将大于等于1MB,那么程序会分配1MB的未使用空间。举个例子,如果进行修改之后,SDS的len将变成30MB,那么程序会分配1MB的未使用空间,SDS的buf数组的实际长度将为30MB+1MB+1byte。

4.2 惰性空间释放可以解决内存泄漏问题,避免频繁分配内存,缺点也是空间浪费。

惰性空间释放用于优化SDS的字符串缩短操作:当SDS的API需要缩短SDS保存的字符串时,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用free属性将这些字节的数量记录起来,并等待将来使用。

5 SDS 二进制安全

例如存了"1234\0123"   \0会被读成结束

redis通过len来表示字符串长度,不会因为中间插入了\0就返回错误结果。

6 C字符串和SDS之间的区别总结

Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS(Simple DynamicString,简单动态字符串)作为字符串表示。

比起C字符串,SDS具有以下优点:

1)常数复杂度获取字符串长度。

2)杜绝缓冲区溢出。

3)减少修改字符串长度时所需的内存重分配次数。

4)二进制安全。

5)兼容部分C字符串函数。

---chenchen

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

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

相关文章

[网络工程师]-STP

生成树协议(Spanning Tree Protocol,STP)是一种链路管理协议,为网络提供路径冗余,同时防止产生环路。交换机之间使用网桥协议数据单元(Bridge Protocol Data Unit,BPDU)来交换STP信息…

C语言中单井号(#)和双井号(##)在宏语句中的应用

在阅读Linux内核代码过程中,特别是一些预处理指令宏的时候,会看到宏语句里会包含一些# 或者是连着的## 符号,刚接触的时候觉得很一头雾水,但这些宏语句有时候绕不开,所以为了更好地读懂这些代码,很有必要仔…

头豹研究院发布《2022年腾讯安全威胁情报能力中心分析报告》:助力企业掌握安全防御主动权

12月23日,头豹研究院发布了《2022年腾讯安全威胁情报能力中心分析报告》(以下简称《报告》),深度研究了腾讯安全威胁情报能力建设、威胁情报能力应用、威胁情报价值实践方面的现状及成果,从专业视角分析腾讯安全威胁情…

全网首发!华为云UCS正式商用

日前,华为云UCS正式商用。华为云UCS是业界首个分布式云原生服务,支持对华为云集群、伙伴云集群、多云集群、本地集群和附着集群的统一管理,覆盖中心Region、专有Region、边缘云、客户数据中心和第三方云场景,提供无处不在的云原生…

深度学习02:损失函数总结

目录 nn.L1Loss: nn.NLLLoss: nn.MSELoss: nn.CrossEntropyLoss: 损失函数是用来估量模型的预测值与真实值的不一致程度,它是一个非负实值函数。我们训练模型的过程,就是通过不断的迭代计算,使用梯度下降的优化算法,使得损失函…

Day 05- Vue3 Vue2响应式原理

Vue2的响应式 核心:通过 Object.defineProtytype() 对对象的已有属性值的读取和修改进行劫持; 数据劫持 --> 给对象扩展属性 --> 属性设置 实现原理: 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截…

风控黑名单库的使用与判断指南

反欺诈策略中有一类策略是专门针对黑名单用户的,我们称之为黑名单命中策略。 一、黑名单定义 黑名单是对严重逾期、骗贷、失联、诈骗等系列高风险客群构建的名单,即为明确非意向客群的名单。黑名单也是反欺诈的第一道防线,可以有效识别黑产客…

近些年大火的零信任,落地情况怎么样?

疫情以来      居家办公、远程工作需求激增      企业IT环境变得更加复杂      在此背景下      以“持续验证,永不信任”为核心的      零信任火爆出圈      引得国内外企业机构纷纷布局      然而根据戴尔2022全球数据保护指数(GDPI),尽管91%的组…

使用FFmpeg+go搭建m3u8点播服务器

一. 前言 HLS(HTTP Live Streaming) 是苹果公司提出的基于 HTTP 的流媒体传输协议,它的工作原理是将整个文件切分成一个个小的文件(通常是 TS 格式文件),客户端通过 HTTP 下载播放。在准备播放某个 m3u8 媒…

Linux系统运行时参数命令--Linux基础命令和工具

目录 1 Linux基础命令和工具 1.1 grep搜索字符 1.2 find查找文件 1.3 ls显示文件 1.4 wc命令 1.5 ulimit用户资源 1.6 scp远程拷贝 1.7 dos2unix和unix2dos 1.8 sed 行处理 简单模式 替换模式 1.9 awk 列处理 C/CLinux服务器开发/后台架构师【零声教育】-学习视频…

车载软件架构—CP和AP相同与不同

文章目录 前言一、两者不同之处二、两者架构设计原则总结前言 AUTOSAR(AUTmotive Open System ARchitecture) 是汽车电子E/E系统发展的一个重要的节点。该标准是由包括BMW、DAIMLER、GM、TOYOTA、福特等主机厂和包括博世、大陆等供应商牵头成立的一个标准发展组织定义的一个开…

45页智慧交通数字化解决方案2022

【版权声明】本资料来源网络,仅用于行业知识分享,供个人学习参考,请勿商用。【侵删致歉】如有侵权请联系小编,将在收到信息后第一时间进行删除! 完整资料领取见文末,部分资料内容: 项目建设目标…

RabbitMQ简单模式

🍁博客主页:👉不会压弯的小飞侠 ✨欢迎关注:👉点赞👍收藏⭐留言✒ ✨系列专栏:👉Linux专栏 🔥欢迎大佬指正,一起学习!一起加油! 目录&…

20 个常用的 pandas 使用技巧

大家好,我是小寒。 今天来分享 20 个常用的 pandas 使用技巧。如果觉得不错,点赞、转发安排起来。 1、以 Markdown 格式输出 DataFrame import pandas as pddf pd.DataFrame({a: [1, 2, 3, 4],b: [5, 6, 7, 8]})# You can control the printing of th…

ATAC-seq分析:教程简介(1)

简介 本课程[1]介绍 Bioconductor 中的 ATACseq 分析。 该课程由 2 个部分组成。这将引导您完成正常 ATACseq 分析工作流程的每个步骤。它涵盖比对、QC、peak calling、基因组富集测试、基序富集和差异可及性测试。 环境准备 IGV IGV 可以从 BROAD 网站安装。 》 https://www.b…

mysql实现行转列作为临时表、以及字符分割行转列

1.需求:实现两个日期段转换为具体的日期天数(2022-10-23至2022-10-26得到一张2022-10-23、2022-10-24、2022-10-25、2022-10-26的临时表) SELECTDATE_FORMAT( DATE_ADD( 2022-10-23 22:00:00, INTERVAL ( help_topic_id ) DAY ), %Y-%m-%d …

微服务洞察,让微服务更透明

作者: 屿山 微服务作为云原生时代下一种开发软件的架构和组织方法,通过将明确定义的功能分成更小的服务,并让每个服务独立迭代,增加了应用程序的灵活性,允许开发者根据需要更轻松地更改部分应用程序。同时每个微服务可…

想不起来的python知识点(应该后续还会再补充)

目录数据类型Number随机生成一个[0,1)范围的实数随机生成一个[1,20)范围内的整数补String(字符串)字符串连接使用join运算符List(列表)由于没有书,利用博客对于Python的学习内容进行简要的记录!(应该是菁(j…

基于声网 Flat 构建白板插件应用“成语解谜”的最佳实践

前言 本文作者赵杭天。他参加了“2022 RTE 编程挑战赛”——“赛道二 场景化白板插件应用开发” , 并凭借作品“成语解谜”获得了该赛道大奖。“成语解谜”是一个基于互动白板 SDK 的互动小游戏应用。通过前端编码、调用白板 API 能力、定制化后端逻辑等&#xff0…

刷题记录:牛客NC17509挖沟[prim+kruskal算法详解]

传送门:牛客 题目描述: 胡队长带领HA实验的战士们玩真人CS,真人CS的地图由一些据点组成,现在胡队长已经占领了n个据点,为了方 便,将他们编号为1-n,为了隐蔽,胡队长命令战士们在每个据点出挖一个坑&#x…