美文网首页
Redis 字符串 SDS 存储大小

Redis 字符串 SDS 存储大小

作者: Yellowtail | 来源:发表于2020-04-27 16:03 被阅读0次

前言

突然对 Redis 里的 字符串存储空间感兴趣了,所以研究一下,分享在这里

更新: 2022-04-12 15:44:48 重新写了一下博客,之前写的貌似是错的 :(

RedisObject

redis 是一个 key-value数据库, 无论是 key, 还是 value, redis 都使用 redisObject 来包裹

结构如下

struct RedisObject {
    int4 type; // 4bits 表示对象的类型,包括5种基本类型
    int4 encoding; // 4bits  表示值对象的内部编码
    int24 lru; // 24bits  记录对象被命令访问的最后一次时间,和内存回收有很大关系
    int32 refcount; // 4bytes = 32bits 记录被引用的次数
    void *ptr; // 8bytes,64-bit system  指向真正内容的指针
}

源码位置是 redisObject

image.png

加起来就是 4 + 4 + 24 + 32 + 64 = 128 bit,也就是 16 字节

SDS

redis 的 key 一定是一个 字符串,所以存储结构是 SDS
我们都知道 Redis 是使用 SDS 数据结构来存储字符串的,原因和好处不是本文关注的重点

数据结构 表述如下( Redis 3.0 版本的结构, 3.0之后变化很大,本文不关注)
3.0 sdshdr

struct sdshdr {
    // 记录 buf 数组中已使用字节的数量
    // 等于 SDS 所保存字符串的长度
    unsigned  int len;

    // 记录 buf 数组中未使用字节的数量
    unsigned  int free;

    // 字节数组,用于保存字符串
    char buf[];
};

3.0 之后的版本,redis 会根据字符串长度的不同,选用不同的结构,如下


image.png

现在着重看一下 3.0 版本,这个版本的字符串结构用泛型来表达就是 RedisObject<Sds>

Key

int 长度为 4字节

初始化的时候,free=0
假设字符串长度为n, 那么 sds 长度为 4+4+n+1 = n+9
1 是因为有个\0

所以对于 redis里的 key-value 来说,key 是 sds,那么长度就是 n+9

再加上外面包裹的 redisObject 的 16字节,所以 key 的长度是 n+25 字节

比如

set a b

那么 a 占了 26字节

Value

value 和 key 的差别在于,value 可以变化,可以 append
初始化的时候,长度和 key 是一样的

value修改 的时候

当第一次追加append的时候,
如果新的大小 new=old+append 小于1MB的时候, 扩容的时候就 翻倍, new=new*2
也就是说,假设原本长度为5, 扩容后变成15,那么扩容后 总长度为30,free变成了15

如果新的大小new 大于1MB(new>1M), 那么总长度是new=new+1Mfree 就是 1MB

当再次追加append的时候,
如果free够用,那么就直接使用
如果不够用,还是按照上面的策略来

缩短的时候

缩短的时候,是一个惰性释放
会把多出来的空间记录到 free里,如果下一次扩容了,说不定能用上
当然了,redis也提供了一些api,可以真正的去释放这些空间

结论

字符串作为 key
长度是 n+25

字符串作为 value
如果没有被改过,那么长度也是 n+25
如果被修改过,那就复杂了

参考

3.0 之后的数据结构参考
简单动态字符串
知乎sds
sds
sds 编码的分界线39

相关文章

  • Redis 字符串 SDS 存储大小

    前言 突然对 Redis 里的 字符串存储空间感兴趣了,所以研究一下,分享在这里 SDS 我们都知道 Redis ...

  • Redis 源码分析(一) :sds

    Redis 源码分析(一) :sds 什么是sds 字符串是Redis中最为常见的数据存储类型,其底层实现是简单动...

  • Redis源码学习基本数据结构之动态字符串sds

    一、sds是什么 字符串是Redis中最为常见的数据存储类型,其底层实现是简单动态字符串sds(simple dy...

  • Redis 五种数据结构

    一、SDS 简单动态字符串 Redis 在存储 可能发生改变、非字面量 的字符串时,都会使用 SDS,比如:red...

  • redis数据结构--SDS

    redis底层存储字符串的数据结构叫做简单动态字符串(simple dynamic string)。 SDS定义 ...

  • Redis 数据结构之SDS

    SDS[simple dynamic string]是redis区别于C语言的字符串存储结构,名曰简单动态字符串;...

  • Simple Dynamic String

    引言 为何redis中大量使用的是SDS,而不是传统的C语言字符串表示法存储字符串?到底什么是SDS?为什么要使用...

  • redis 数据结构

    String 数据结构 示例 这里就可以存储"Redis C",而C只能读取Redis字符串 对C字符串和SDS之...

  • 《redis设计与实现》读书笔记一

    Redis构建了一种简单动态字符串(SDS),并将SDS用作redis的默认字符串表示 通过使用SDS,将获取字符...

  • Redis 的动态字符串实现(2)

    Redis 的动态字符串实现sds.h和 sds.c 1.优化点,根据len 大小决定需要的使用数据结构,节省空间...

网友评论

      本文标题:Redis 字符串 SDS 存储大小

      本文链接:https://www.haomeiwen.com/subject/gynywhtx.html