redis底层数据结构之简单动态字符串(SDS)
简单动态字符串(simple dynamic string,SDS)
redis使用C语言编写的,但是redis的字符串却不是C语言中的字符串(以空字符'\0'结尾的字符数组),redis定义了一种简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS作为redis的默认字符串
1 SDS结构
struct sdshdr {
int len;
int free;
char buf[];
}
其中:
len:记录buf数组中已使用字节的长度,等于buf[]中字符串的长度
free:记录buf数组中未使用字节的长度
buf[]:字节数组,用于保存字符串
2 SDS结构示意图
encoding = REDIS_ENCODING_INT 或 REDIS_ENCODING_EMBSTR 或 REDIS_ENCODING_RAW
分配了10Byte空间,占用了6Byte,未使用4Byte
保存空字符的1Byte不包含在len属性里,redis默认为空字符分配额外的1Byte,并把空字符添加到字符串末尾,这些操作都由SDS函数自动完成
示意图如下:

3 redis使用SDS的优点
1) 常数复杂度获取字符串长度
获取SDS字符串的长度只需要读取len属性,时间复杂度为O(1);而C语言中获取字符串的长度通常是经过遍历计数来实现的,时间复杂度为O(n)
2) 杜绝缓冲区溢出
C语言中使用strcat函数来进行字符串的拼接,一旦没有分配足够的内存空间,就会造成缓冲区溢出
而SDS在修改字符串时,首先根据len属性检查内存空间是否满足需求,如果不满足,会进行空间扩展然后在修改,所以不会出现缓冲区溢出
3) 减少修改字符串的内存重新分配次数
C语言不记录字符串的长度,修改字符串时必须要重新分配内存(先释放再申请),如果不重新分配内存,字符串长度增大时会造成内存缓冲区溢出,字符串长度减小时会造成内存泄露
而SDS修改字符串时使用空间预分配和惰性空间释放两种策略:
a) 空间预分配:对字符串进行空间扩展时,扩展的内存比实际需要的多(修改后的字符串小于1MB时,那么会分配与len属性相同大小的未使用空间;大于1MB时,会分配1MB的未使用空间),这样可以减少连续执行字符串增长操作所需的内存重分配次数
b) 惰性空间释放:对字符串进行缩短操作时,不会立即回收缩短后剩余的内存空间,而是使用free属性将剩余的内存空间记录下来,等待后续使用(当有需要时,也可以手动释放这些未使用的空间)
4) 二进制安全
C字符串是以空字符作为字符串结束的标识,而二进制文件(如图片等)内容可能包括空字符串,因此C字符串无法正确存取
而SDS不是以空字符作为字符串结束的标识,而是以len属性表示的长度来判断字符串是否结束
5) 兼容部分C字符串函数
虽然SDS是二进制安全的,但是一样遵从每个字符串都是以空字符串结尾的惯例,这样可以重用C语言库<string.h>中的一部分函数
redis底层数据结构之简单动态字符串(SDS)的更多相关文章
- 【redis】redis底层数据结构原理--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表等
redis有五种数据类型string.list.hash.set.zset(字符串.哈希.列表.集合.有序集合)并且自实现了简单动态字符串.双端链表.字典.压缩列表.整数集合.跳跃表等数据结构.red ...
- 图解Redis之数据结构篇——简单动态字符串SDS
图解Redis之数据结构篇--简单动态字符串SDS 前言 相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象 ...
- Redis数据结构之简单动态字符串SDS
Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...
- redis 系列3 数据结构之简单动态字符串 SDS
一. SDS概述 Redis 没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默 ...
- Redis 数据结构之简单动态字符串SDS
几个概念1:key对象 数据库存储键值对的键,总是一个字符串对象.2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象. ...
- Redis底层探秘(一):简单动态字符串(SDS)
redis是我们使用非常多的一种缓存技术,他的性能极高,读的速度是110000次/s,写的速度是81000次/s.这么高的性能背后,到底是怎么样的实现在支撑,这个系列的文章,我们一起去看看. redi ...
- 深入理解Redis 数据结构—简单动态字符串sds
Redis是用ANSI C语言编写的,它是一个高性能的key-value数据库,它可以作用在数据库.缓存和消息中间件.其中 Redis 键值对中的键都是 string 类型,而键值对中的值也是有 st ...
- 【Redis】简单动态字符串SDS
C语言字符串 char *str = "redis"; // 可以不显式的添加\0,由编译器添加 char *str = "redis\0"; // 也可以添加 ...
- Redis数据结构之简单动态字符串
Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组), 而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将SDS用作Redi ...
- Redis源码解析:01简单动态字符串SDS
Redis没有直接使用C字符串(以'\0'结尾的字符数组),而是构建了一种名为简单动态字符串( simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默认字符 ...
随机推荐
- List_集合_介绍&常用方法-ArrayList集合
List_集合_介绍&常用方法 我们掌握了Collection接口的使用后,再来看看Collection接口中的子类,他们都具备那些特性呢?接下来,我们一起学习Collection中的常用几个 ...
- Java 进阶P-8.5+P-8.6
抛出异常 异常的抛出与声明 如果你的函数可能抛出异常,就必须在函数头部加以声明 你可以声明并不会真的抛出得异常 什么能扔? 任何继承了Throw able类的对象 Exception类继承了Throw ...
- 数据湖Hudi与对象存储Minio及Hive\Spark\Flink的集成
本文主要记录对象存储组件Minio.数据湖组件Hudi及查询引擎Hive\Spark之间的兼容性配置及测试情况,Spark及Hive无需多言,这里简单介绍下Minio及Hudi. MinIO 是在 G ...
- react 高效高质量搭建后台系统 系列 —— 表格的封装
其他章节请看: react 高效高质量搭建后台系统 系列 表格 有一种页面在后台系统中比较常见:页面分上下两部分,上部分是 input.select.时间等查询项,下部分是查询项对应的表格数据.包含增 ...
- spring cloud alibaba - Nacos 下载安装
1.关于名字 前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service 2.是什么 一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心.是注册中心和配 ...
- 云端智创 | 批量化生产,如何利用Timeline快速合成短视频?
本文内容整理自「智能媒体生产」系列课程第三讲:开发者实战,由阿里云智能视频云技术专家分享云剪辑Timeline的功能及使用方法.云剪辑OpenAPI的使用流程.短视频批量生产的基本原理以及使用Time ...
- 为K8S集群准备Ceph存储
随着K8S存储接口逐渐成熟并顺势推出CSI接口规范后,原来"in-tree"(树内)模式的很多存储插件也逐步迁移到了"out-of-tree"(树外)模式的CS ...
- .NET Core Redis的简单使用
1.Redis简介 Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库. 2.Redis主要特点 Redis支持数据的持久化 Redis支持多种数据结构 Redi ...
- 快速上手Java开发工具Eclipse之简易手册
Eclipse下载,可以下载最新版本,文档是以2020-12R版本为例 http://www.eclipse.org/downloads/ 下载Packages即可 安装Eclipse 解压安装 除了 ...
- SnowFlake 雪花算法详解与实现 & MP中的应用
BackGround 现在的服务基本是分布式,微服务形式的,而且大数据量也导致分库分表的产生,对于水平分表就需要保证表中 id 的全局唯一性. 对于 MySQL 而言,一个表中的主键 id 一般使用自 ...