美文网首页
Redis基础数据结构--string(字符串)

Redis基础数据结构--string(字符串)

作者: 酷癫 | 来源:发表于2020-03-30 21:31 被阅读0次

    Redis有5种基础数据结构,分别是:string(字符串),list(链表),hash(字典),set(集合),zet(有序链表)。

    string(字符串)

    Redis中的字符串是一个可修改的字符串,在内存中以字节数组的形式存储,字符串也叫做 Simple Dynamic String,结构如下:

    struct SDS<T> {
      // 数组容量
      T capacity; 
       // 数组长度
      T len;
      // 特殊标识位
      byte flags; 
      // 数组内容
      byte[] content;
    }
    

    其中,content存储的是真正的字符串内容,capacity表示所分配的数组长度,len表示字符串的长度,当数组没有冗余空间,追加内容时会分配新的数组,将旧数组中的内容拷贝出来,再append新的内容。

    redis规定字符串的最大长度为512MB,创建字符串时len和capacity一样长,不分配新的冗余空间。

    embstr vs raw

    redis的字符串有两种存储方式,在长度特别短的时候,用emb形式存储,当长度超过44时,使用raw形式存储。这两种存储方式结构如下:

    embstr vs .png

    为什么长度为44?

    1.先看下redis的对象头结构

     struct RedisObject {
        int4 type; // 4bits
        int4 encoding; // 4bits
        int24 lru; // 24bits
        int32 refcount; // 64bits
        void *ptr; // 64bits
    } robj;
    

    整个RedisObject对象头需占16个字节。

    2.从文章开头我们可以看到,SDS的结构使用的是范型,当字符串比较短时,len和capacity可以使用byte和short表示,所以最小的对象头大小为content的长度+3,结构如下:

    struct SDS {
       // 1byte
      int8 capacity; 
      // 1byte
      int8 len; 
      // 1byte
      int8 flags; 
      // 内联数组,长度为 capacity 
      byte[] content; 
    }
    

    redis为容纳一个完整的 embstr 对象,内存分配器最少会分配 32 字节的空间,如果字符串再稍微长一点,那就是 64 字节的空间。如果总体超出了 64 字节,Redis 认为它是一个大字符串,不再使用 emdstr 形式存储,而该用 raw 形式。

    存储字符串长度计算如下:
    RedisObject = type(4bits)+encoding(4bits)+LRU(24bits)+refcount(64bits)+ptr(64bits);
    SDS = capacity(8bits)+len(8bits)+flags(8bits)+content;
    content剩余最多的长度只有45(64-19),而content中的字符串又是已 \0结尾,所有 embstr最大的字符串长度为44。

    扩容策略

    字符串的长度在小于1M时,扩容采用加倍策略,当长度大于1M时,为避免加倍的冗余空间过大而导致浪费,每次分配只会多1M的冗余空间。

    相关文章

      网友评论

          本文标题:Redis基础数据结构--string(字符串)

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