Redis的设计与实现 简单动态字符串SDS

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,倚天版 1GB 1个月
简介: Redis的设计与实现 简单动态字符串SDS

一 SDS的定义

  • Redis没有使用C语言传统的字符串表示,他自己构建了一个简单动态字符串的抽象类型,他就是SDS,redis里面C字符串只会用来无需对字符串进行修改的地方,比如打印日志
  • 数据结构

    struct sdshdr {

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

    }

image.png

sds遵循空字符串结尾,因为这样可以直接重用C字符串里面的一些函数比如打印
printf("%s",s->buf)

二 SDS与C字符串的区别

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

    记录自身的长度信息,所以每次获取长度都要遍历,而SDS通过len可以直接得到长度信息,节省性能

  2. 杜绝缓存区溢出

    C语言的字符串不记录自身的长度信息,所以在执行strcat向一个字符串结尾追加另一个字符串时,如果不先扩容,就会把前面的字符串覆盖掉,造成缓存区溢出

  3. 减少修改字符串时带来的内存重分配次数

    C语言的字符串不记录自身的长度信息,增加字符串就要扩容计算,就要重新分配,而SDS通过空间预分配,和惰性空间释放来减少内存重分配

    • 空间预分配

      如果占用空间小于1M,那么就分配和len同样的长度,也就是free空间

    • 惰性空间释放

      当字符串被删除,free空间并不跟着删除,这样下次增加的时候,就可以直接用free的空间

  4. 二进制安全

    C字符串必须符合某种编码,但是有些编码对字符串的判断不一样,比如 redis look,中间有一个空格,对与某个编码可能就是要换行,导致问题,但是SDS判断字符串结束是通过len属性,所以不会有问题。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
存储 NoSQL Redis
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
61 1
|
4天前
|
NoSQL Java Redis
Redis字符串数据类型之INCR命令,通常用于统计网站访问量,文章访问量,实现分布式锁
这篇文章详细解释了Redis的INCR命令,它用于将键的值增加1,通常用于统计网站访问量、文章访问量,以及实现分布式锁,同时提供了Java代码示例和分布式锁的实现思路。
12 0
|
1月前
|
存储 NoSQL Redis
Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
|
2月前
|
机器学习/深度学习 XML NoSQL
【Redis】 String 字符串类型常见命令
【Redis】 String 字符串类型常见命令
|
2月前
|
NoSQL Java Redis
【Redis】 Java操作Redis客户端命令——基础操作与字符串操作
【Redis】 Java操作Redis客户端命令——基础操作与字符串操作
|
4天前
|
NoSQL 数据可视化 Redis
Mac安装Redis
Mac安装Redis
14 3
|
4天前
|
NoSQL Ubuntu 安全
在Ubuntu 18.04上安装和保护Redis的方法
在Ubuntu 18.04上安装和保护Redis的方法
14 0
|
4天前
|
存储 NoSQL Java
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
该博客文章展示了如何在Linux虚拟机上使用Redis和Jedis客户端实现手机验证码的验证功能,包括验证码的生成、存储、验证以及限制每天发送次数的逻辑,并提供了测试结果截图。
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
|
5天前
|
NoSQL Linux 网络安全
Linux系统安装Redis
该博客文章详细介绍了在Linux系统中安装Redis的步骤,包括下载、编译、配置、启动Redis服务以及使用客户端访问Redis数据库的过程。
Linux系统安装Redis
|
8天前
|
NoSQL Redis Docker
Docker 安装 Redis
Docker 安装 Redis
35 2