Redis系列之底层数据结构SDS
Redis系列之底层数据结构SDS
实验的环境
- Redis 6.0
- VSCode 1.88.1
什么是SDS?
SDS:Simple Dynamic String,翻译为简单动态字符串。SDS是一种用于存储二进制数据的数据结构,具有动态扩容的特点,代码位于src/sds.h和src/sds.c
SDS的总体数据结构大致如图:在源码里sds包括几个部分,len、alloc、flags、buf,其中 sdshdr是头部,buf是真实存储数据的地方,在存储的数据后面会跟一个\0,所以数据加上\0就是所谓的buf

- len:保存了SDS字符串的长度
- buf[]:保存数据的地方
- alloc:分别以uint8, uint16, uint32, uint64表示整个SDS
- flags:始终为一字节, 以低三位标示着头部的类型, 高5位未使用
查看源码sds.h,可以看到SDS里面有几种不同的头部,其中sdshdr5实际并未使用到,所以实际上有四种不同的头部
/* Note: sdshdr5 is never used, we just access the flags byte directly.* However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 3 lsb of type, and 5 msb of string length */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; /* used */uint8_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len; /* used */uint16_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; /* used */uint32_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {uint64_t len; /* used */uint64_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
为什么要使用SDS?
Redis是用C语言写的,为什么不直接就用C语言里的char来定义字符串?
- 获取字符串长度
由于有len属性,所以获取SDS字符串的长度只需要读取len属性,所以时间复杂度为O(1)。如果直接使用C语言中的字符串来实现,获取字符串的长度需要遍历计数,时间复杂度为O(n)。
- 避免缓存区溢出
在C语言中,如果使用strcat函数来进行两个字符串的拼接,如果没有分配足够长度的内存空间,就会造成缓存区溢出。而对于SDS数据类型,在进行字符串修改的时候,会根据记录的len属性检查内存空间是否满足需求,如果不满足,会进行相应空间的扩展,所以不会出现缓存区溢出
- 减少字符串内存重新分配次数
在C语言中字符串,是不会记录字符串的长度的,所以一旦修改了字符串,就需要重新分配内存,因为如果没有重新分配,字符串长度增大时会造成内存溢出区溢出,长度减小时会造成内存泄漏。而对于SDS来说,因为有长度熟悉len和alloc属性的存在,SDS实现了空间预分配和惰性空间释放两种策略来减少重新分配内存
- 空间预分配:SDS对空间进行扩展的时候,扩展的内存比实际需要的多,这样可以减少字符串增长操作所需的内存重新分配次数
- 惰性空间释放:SDS对字符串进行缩短操作时,不会立即进行内存重新分配,来回收缩短后多余的内存空间,而是使用
alloc将这些字节数量记录下来,等待后续使用
- 二进制安全
在C语言中,是以空字符串作为字符串结束的标识,但是一些特殊的字符串,可能就包括空字符串的,所以容易丢失数据,不能正确存取。而SDS是根据len属性,以处理二进制的方式来处理buf里的数据,所以保存数据更加安全
- 兼容部分C字符串函数
SDS可以重用C语言库<string.h>中的一部分函数
C字符串和SDS对比
| C字符串 | SDS |
|---|---|
| 获取字符串长度时间复杂度为O(n) | 获取字符串的长度时间复杂度为O(1) |
| 不安全,可能会造成缓冲区溢出 | 安全,不会造成缓冲区溢出 |
| 修改字符串n次就需要进行n次内存分配 | 修改字符串长度n次,最多需要n次内存分配 |
| 只能保存文本数据 | 可以保存文本数据或者二进制数据 |
| 可以使用所有<string.h>库中的函数 | 可以使用一部分<string.h>库中的函数 |
相关文章:
Redis系列之底层数据结构SDS
Redis系列之底层数据结构SDS 实验的环境 Redis 6.0VSCode 1.88.1 什么是SDS? SDS:Simple Dynamic String,翻译为简单动态字符串。SDS是一种用于存储二进制数据的数据结构,具有动态扩容的特点,代码位于src/sds.h和src/sds.c …...
【STM32】esp8266连接wifi
1.配置stm32cubemx 使用串口二接收esp8266的数据,单片机接收,使用串口1将数据发送给串口助手 串口2波特率设置74880,串口1设置115200 在初始化的时候需要将复位引脚拉低20ms,然后再拉高20ms, 设置GPIOB的输出模式 对PB12做输出处理 2.…...
网络运维故障处理
本篇纯是之前的工作经验做一个分享,大家看个热闹就好。 1.突然的断网,在上家上班的时候,有一天突然下午厂区内开始出现大面积网络卡顿,teams,outlook不好使等情况,且网盘也上不去,所以开始排查…...
C++第十一节课 new和delete
一、new和delete操作自定义类型 new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数(new会自动调用构造函数;delete会调用析构函数) class A { public:A(int a 0): _a(a){cout <&l…...
【爱给网-注册安全分析报告-无验证方式导致安全隐患】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…...
苹果为什么不做折叠屏手机?
苹果为什么不做折叠屏手机?折叠屏手机在最近这些年里边,可以说是市场的一个主要在手机上的增长点。你像华W最近推出这个三折叠手机,引起了整个市场的轰动。 可是,为什么苹果到今天为止不为所动,还在那不停地在现在的这…...
目标检测经典算法的个人理解
one stage 1、RCNN -> Fast-RCNN:RPN部分从用传统的算法 -> 用深度学习网络来实现。 2、Fast-RCNN -> Faster-RCNN:从先选region再求Feature -> 先求Feature再选region。 two stage 1、SSD(2016):VGG做…...
FewShotChatMessagePromptTemplate 和 FewShotPromptTemplate区别
FewShotChatMessagePromptTemplate 和 FewShotPromptTemplate 都是 LangChain 框架中用于少样本学习的提示模板(Prompt Template),但它们在设计和用途上存在一些区别。 FewShotChatMessagePromptTemplate 用途:主要用于聊天场景…...
《程序猿之设计模式实战 · 策略模式》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...
deepinlinux-v23用deepinunioncode初始c例子
deepinlinux-v23用deepinunioncode初始c例子 # deepinunioncode 新建duc工程cmake模版,开局提示 No CMAKE_CXX_COMPILER could be found错误记录 需要duc 左下角磁轮设置 设置cmake和gcc g的文件,如果本机装过了(apt install gc…...
前端框架对比选择:如何在众多技术中找到最适合你的
引言 在现代Web开发中,前端框架的选择对项目的成功与否至关重要。随着技术的不断发展,市面上涌现出多种前端框架,每种框架都有其独特的特点、优缺点以及适用场景。本文将对当前主流的前端框架进行详细对比,帮助开发者在选择时做出…...
数据结构—(java)反射,枚举,lambda表达式
文章目录 反射反射的定义:反射相关的类:反射相关的方法:反射示例:获取Class类对象创建指定类的对象反射私有属性:反射私有方法:反射私有的构造方法 枚举枚举的意义枚举类的实现枚举类的使用:Enu…...
机器学习(西瓜书)第 14 章 概率图模型
14.1 隐马尔可夫模型 机器学习最重要的任务,是根据一些已观察到的证据(例如训练样本)来对感兴趣的未知变量(例如类别标记)进行估计和推测。概率模型(probabilistic model)提供了一种描述框架&a…...
Python异步编程-asyncio详解
目录 asyncio简介示例什么是 asyncio?适用场景API asyncio的使用可等待对象什么是可等待对象?协程对象任务对象Future对象 协程什么是协程?基本使用运行协程 Task什么是 Task?创建 Task取消 TaskTask 异常获取Task 回调 TaskGroup什么是 Tas…...
UniApp如何打包成客户端应用程序
像flutter是支持PC宽屏、桌面平台(Windows/macOS/Linux),我一直在期望UniApp什么时候也支持PC,桌面平台,终于盼到了。 1、支持PC宽屏 从uni-app 2.9起,支持PC宽屏的适配。 uni-app提供的屏幕适配方案&am…...
你应该掌握的12条饭局规矩!
在职场的舞台上,饭局不仅仅是一场简单的聚餐,它是一场精心编排的社交盛宴,是展示个人魅力、构建人脉网络的重要平台。精通饭局的艺术,能让你在职场的交际中更加自如。以下是酱酒亮哥整理的12条饭局指南,希望你在职场的…...
【541. 反转字符串 II 简单】
题目: 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。 如果剩余字符少于 k 个,则将剩余字符全部反转。如果剩余字符小于 2k 但大于或等于 k 个,…...
基于PHP的丽江旅游管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的丽江旅游管理系统 一 介绍 此丽江旅游系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈:phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销…...
vue3+Element-plus el-input 输入框组件二次封装(支持金额、整数、电话、小数、身份证、小数点位数控制,金额显示中文提示等功能)
一、效果图 二、组件集成了以下功能 1、输入金额--支持千分号显示、可设置decimalLimit来调整小数点位数 2、金额鼠标移入提示中文--标签添加isTip开启中文提示则不允许开启千分号显示showThousands 3、输入手机号--设置inputTypephone 4、输入整数---设置inputTypeinteger 5、…...
jQuery 简介 ③ ready()事件函数、jQuery 二个原则及容错机制
文章目录 jQuery 简介 ③五、ready() 准备就绪时执行代码六、jQuery 核心1、Get and Set in One 原则2、Get first Set all 原则3、容错机制:jQuery 简介 ③ 五、ready() 准备就绪时执行代码 如果我们在中引入jQuery库文件,并编写相应的jQuery代码来操作DOM元素。这很可能导…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
