Redis是是以K-V的形式存储数据的.其中V的数据类型有多种,如String,List,Hash,Set,Zset等.而K的数据类型只是String.

在Redis中,无论哪种数据类型,其抽象模型都是redisObject,

typedef struct redisObject{
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:Lru_BITS;
    int refcount;
    void *ptr;
} robj

其中:

  • type--数据类型
  • encoding:编码格式
  • lru:时间戳
  • redcount:引用计数
  • ptr:指向实际的数据结构

对于String数据类型,ptr指向的数据结构就是sds.

sds是redis中自定义的数据结构,与c语言中字符串以空白字符结尾不同的是,sds对字符串类型做了扩展,有如下优点:

  • 可以在O(1)时间获取到字符串的长度
  • 可以存放空字符
  • 是二进制安全,可以存放任意二进制数据

sds结构体可以分为sdshdr5,sdshdr8,sdshdr16,sdshdr32,sdshdr64

除了sdshdr5意外,其余几种结构体都维护了以下4个信息:

  • len--字符串的长度
  • alloc:已经申请的字符串长度
  • flags--sds类型
  • buf--字符串内容(数组)

sdshdr5中仅有flags和buf字符段.flags低3位代表sds类型,高5位代表字符串长度,并且sdshdr5是常量字符串,不支持扩容.

sds设计不同类型的原因是可以根据字符串的长度选择不同合适的len,alloc属性,最大限度地节省内存.

sds字符串的编码有三种,分别为EMBSTR,RAW,INT.

EMBSTR针对短字符串进行了优化,redisObject和sds在一块连续的内存空间之内(len<44>) 

RAW针对长字符串(len>44) redisObject和sds在两块不同的内存区域.

INT针对整数型字符串并且长度小于等于20,将转为long long类型