Redis 源码硬核解析系列专题 - 第二篇:核心数据结构之SDS(Simple Dynamic String)

1. 引言

Redis没有直接使用C语言的标准字符串(以\0结尾的字符数组),而是自定义了SDS(Simple Dynamic String)。SDS是Redis的基础数据结构之一,广泛用于键值存储、命令参数等场景。本篇将深入剖析SDS的实现原理、优势以及源码细节。


2. 为什么不用C标准字符串?

C字符串存在以下问题:

  • 缓冲区溢出strcat等操作可能越界。
  • 长度计算:需要遍历到\0,时间复杂度O(n)。
  • 内存管理:频繁的拼接和释放效率低下。

SDS通过额外的元数据和优化策略,解决了这些问题,成为Redis高性能的基石。


3. SDS的结构体定义

SDS的定义在src/sds.hsrc/sds.c中。Redis 3.2之后引入了多种SDS类型以节省内存,但核心思想一致。我们以最基本的SDS结构为例:

代码片段sds.h):

typedef char *sds;struct sdshdr {unsigned int len;    // 已使用长度unsigned int free;   // 未使用长度char buf[];          // 实际存储数据的柔性数组
};
  • len:记录字符串的实际长度,避免遍历。
  • free:记录剩余可用空间,支持动态扩展。
  • buf:存储字符串内容,紧跟结构体。

硬核点:SDS的内存布局是连续的,sds指针直接指向buf,而通过指针偏移可以访问sdshdr

Mermaid内存布局图

classDiagramclass SDS {-len: uint-free: uint-buf: char[]}note for SDS "sds指针指向buf起始地址"

4. SDS的核心操作解析
4.1 创建SDS(sdsnew()

代码片段sds.c):

sds sdsnew(const char *init) {size_t initlen = (init == NULL) ? 0 : strlen(init);return sdsnewlen(init, initlen);
}sds sdsnewlen(const void *init, size_t initlen) {struct sdshdr *sh;size_t alloc = initlen;sh = zmalloc(sizeof(struct sdshdr) + alloc + 1); // +1 为\0sh->len = initlen;sh->free = 0;if (init) memcpy(sh->buf, init, initlen);sh->buf[initlen] = '\0';return (char*)sh->buf;
}

硬核解析

  • zmalloc():Redis自定义的内存分配器。
  • 内存分配包括sdshdr头部和buf(加1字节存放\0以兼容C函数)。
  • 返回值是buf的地址,隐藏了头部信息。
4.2 拼接SDS(sdscat()

代码片段sds.c):

sds sdscat(sds s, const char *t) {return sdscatlen(s, t, strlen(t));
}sds sdscatlen

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

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

相关文章

python-59-基于python内置库解析html获取标签关键信息

文章目录 1 html.parser1.1 初始化和基础使用1.1.1 handle_starttag(self, tag, attrs)1.1.2 handle_endtag(self, tag)1.1.3 handle_startendtag(self, tag, attrs)1.1.4 handle_data(self, data)1.1.5 handle_comment(self, data)1.2 解析HTML文档的流程2 百度搜索关键词链接…

Java的string默认值

在Java中,String类型的默认值取决于其定义和实例化的方式。 以下是关于String默认值的详细说明 未实例化的String变量‌ 如果定义一个String变量但未对其进行实例化(即未使用new关键字或直接赋值),其默认值为:ml-search[null]。这…

高并发系统下的订单号生成服务设计与实现

目录 引言 订单号设计的关键考量因素 基础需求分析 唯一性保障 数据量预估 可读性设计 系统架构考量 分库分表兼容 可扩展性设计 技术选型与比较 性能优化 高可用性保障 实践案例:高并发系统订单号结构设计 结构详解 业务类型标识(2位) 唯一标识部分…

使用LLaMAFactory微调Qwen大模型

一、环境配置与工具安装 1. 硬件要求 GPU:至少1块NVIDIA GPU(推荐RTX 4090/A100/H100,显存≥16GB)。内存:≥64GB系统内存。存储:≥100GB硬盘空间用于模型与数据集存储。2. 软件依赖 Python 3.8+:需安装CUDA支持的PyTorch版本(如torch==2.0.1+cu117)。 依赖库:通过以…

2025-3-29算法打卡

一,回文判定 1.题目描述: 题目描述 给定一个长度为 nn 的字符串 SS。请你判断字符串 SS 是否回文。 输入描述 输入仅 11 行包含一个字符串 SS。 1≤∣S∣≤1061≤∣S∣≤106,保证 SS 只包含大小写、字母。 输出描述 若字符串 SS 为回…

Android 接 Twitter Share ,常见问题及解决方案

1. 应用未授权或授权失败 问题描述:当尝试分享内容到 Twitter 时,应用提示未授权,或者在授权过程中出现错误,无法获取授权码或访问令牌。解决方案 检查 Twitter API 密钥和密钥密码:确保在 Twitter 开发者平台创建应用后,获取的 API 密钥(Consumer Key)和 API 密钥密码…

【数据结构】树与森林

目录 树的存储方法 双亲表示法 孩子表示法 孩子兄弟表示法 树、森林与二叉树的转换 树转换成二叉树 森林转换成二叉树 二叉树转换成森林 树与森林的遍历 树的遍历 森林的遍历 树的存储方法 双亲表示法 这种存储结构采用一组连续空间来存储每个结点,同时…

html5基于Canvas的动态时钟实现详解

基于Canvas的动态时钟实现详解 这里写目录标题 基于Canvas的动态时钟实现详解项目介绍技术栈项目架构HTML结构核心样式设计 核心功能实现1. 时钟表盘绘制2. 时钟指针动画3. 主题切换实现4. 时间格式切换 技术要点总结项目亮点总结参考资料 项目介绍 在这篇文章中,我…

Deepseek API+Python 测试用例一键生成与导出 V1.0.3

** 功能详解** 随着软件测试复杂度的不断提升,测试工程师需要更高效的方法来设计高覆盖率的测试用例。Deepseek API+Python 测试用例生成工具在 V1.0.3 版本中,新增了多个功能点,优化了提示词模板,并增强了对文档和接口测试用例的支持,极大提升了测试用例设计的智能化和易…

react如何引用(按需加载)百度地图,并结合and组件化封装

1.技术选项: vitereactantdesign load-script 2.实现思路: 1.按需加载如何实现? 要实现按需加载就不能直接在项目的入口文件这种地方去通过script标签引入,这里使用load-script封装了一个加载百度地图的Bmap.js方法,实现动态的插入script脚本。 根…

LeetCode 第31~33题

目录 LeetCode 第31题:下一个排列 LeetCode 第32题:最长有效括号 LeetCode 第33题:搜索旋转排序数组 LeetCode 第31题:下一个排列 题目描述 整数数组的一个排列就是将所有成员以序列或线性顺序排列。例如arr[1,2,3],以…

虚拟现实--->unity学习

前言:这学期劳动课选了虚拟现实,其中老师算挺认真的,当然对一些不感兴趣的同学来说是一种折磨,我对这个unity的学习以及后续的虚幻引擎刚开始连基础的概念都没有,后面渐渐也是滋生了一些兴趣,用这篇博客记录…

在Trae中设置Python解释器版本

Python 是一种广泛使用的高级编程语言,因其简洁易读的语法和强大的功能而备受欢迎。随着 Python 的不断发展,多个版本相继发布,每个版本都带来了新特性和改进。然而,这也带来了一些问题,比如不同的工程,需要…

鸿蒙原生开发之状态管理V2

一、ArkTS状态变量的定义: State:状态,指驱动UI更新的数据。用户通过触发组件的事件方法,改变状态数据。状态数据的改变,引起UI的重新渲染。 在鸿蒙原生开发中,使用ArkTS开发UI的时候,我们可以…

nginx配置跳转设置Host有误导致报404问题

我们有个项目,前端调用了第三方接口。为了避免跨域,所以使用nginx进行转发。一直正常工作,相安无事。近日第三方调整了安全策略,http转换成https,原本使用ip,现在也改成使用域名,所以nginx这里我…

深度学习 Deep Learning 第12章 深度学习的主流应用

深度学习 Deep Learning 第12章 深度学习的主流应用 内容概要 本周深入探讨了深度学习在多个领域的应用,包括计算机视觉、语音识别、自然语言处理以及其他领域如推荐系统和知识表示。本章强调了硬件和软件基础设施的重要性,特别是GPU在加速神经网络训练…

【Qt】三种操作sqlite3的方式及其三种多表连接

一、sqlite3与MySQL数据库区别: 1. 数据库类型 SQLite3:是嵌入式数据库,它将整个数据库存储在单个文件中,不需要独立的服务器进程。这意味着它可以很方便地集成到各种应用程序中,如移动应用、桌面应用等。MySQL&…

mysqlworkbench导入.sql文件

1、MySQL Workbench 新建数据库 或者 在左侧导航栏的 ​Schemas 区域右键选择 ​Create Schema...输入数据库名称(例如 mydatabase),点击 ​Apply确认创建,点击 ​Finish 2、选择目标数据库 在左侧导航栏的 ​Schemas 列表中&a…

《Spring Cloud Eureka 高可用集群实战:从零构建高可靠性的微服务注册中心》

从零构建高可用 Eureka 集群 | Spring Cloud 微服务架构深度实践指南 本文核心内容基于《Spring Cloud 微服务架构开发》第1版整理,结合生产级实践经验优化 实验环境:IntelliJ IDEA 2024 | JDK 1.8| Spring Boot 2.1.7.RELEASE | Spring Cloud Greenwich…

实变函数:集合与子集合一例(20250329)

题目 设 r , s , t r, s, t r,s,t 是三个互不相同的数,且 A { r , s , t } A \{r, s, t\} A{r,s,t}, B { r 2 , s 2 , t 2 } B \{r^2, s^2, t^2\} B{r2,s2,t2}, C { r s , s t , r t } C \{rs, st, rt\} C{rs,st,rt} 若 A B C A B C ABC 则 { r , s…