redisObject

五种对象

  • string(int + embstr sds+ raw sds)
  • list(ziplist + linkedlist)
  • hash(ziplist + dictht)
  • set(intset + dictht)
  • zset(ziplist + (skiplist+dictht))

Redis中每个对象都由redisObject结构表示,分别是type,encoding,ptr

typedef struct redisObject{

    //类型,共5种
    unsigned type:4;
    //编码,即真正使用的数据结构
    unsigned encoding:4;
    //指针指向数据结构
    void *ptr;
    //引用计数
    int refcount;
    //最后一次被访问的时间
    unsigned lru:22;
    
    // 未使用的两个位
    unsigned notused:2; /* Not used */

}robj;

type:5种

REDIS_STRING:字符串

REDIS_LIST:列表

REDIS_HASH:哈希表

REDIS_SET:集合

REDIS_ZSET:有序集合

encoding:8种

int:long类型整数

embstr:字符串

raw:字符串

ht:dictht字典

linkedlist:双端链表

ziplist:压缩链表

intset:整数集合

skiplist:跳跃表 

string:3种

int:普通整数

embstr:<=32字节的字符串

raw(sds):>32字节的字符串

list:2种

ziplist:所有元素(StringObject)长度<64字节并且元素数量<512

linkedlist:不满足ziplist的条件

hash:2种

ziplist:所有key和value长度<64字节并且键值对数量<512

dictht:不满足dictht

set:2种

intset:所有都是整数且数量<512

dictht:不满足intset

zset:2种

ziplist:所有元素长度<64字节且数量<128

skiplist+dictht:不满足ziplist

1.string对象(int/ embstr/ raw)

(1) 整数用long类型表示

redis 塞对象 redis 对象列表_redis 塞对象

(2) >32字节的字符串用raw(sds)表示

redis 塞对象 redis 对象列表_字符串_02

(3)<=32字节的字符串用embstr(sds)表示

与raw的区别是:embstr的redisObject和sdshdr结构只调用了一次内存分配,内存是连续的。释放也只需要一次

而raw调用了两次内存分配,因此内存是不连续的。释放内存需要两次

embstr是只读的。

redis 塞对象 redis 对象列表_字符串_03

其他:

1.double类型的浮点数或者超出long范围的整数,会转化成sds来存储。

2.int和embstr都会转化成raw:整数类型如果append字符串会转成raw;embstr是只读的,如果修改也会变成raw。

2.list对象(ziplist/ linkedlist)

(1)ziplist

需要满足两个条件:所有字符串长度<64字节并且元素数量<512

每个列表元素用entry存储(如 1, three, 5)

redis 塞对象 redis 对象列表_redis 塞对象_04

(2)linkedlist

不满足ziplist的条件时会被转换成linkedlist

redis 塞对象 redis 对象列表_redis 塞对象_05

3.hash对象(ziplist/ dictht)

(1)ziplist

需要满足两个条件:所有key和value长度<64字节并且键值对数量<512

key和value紧挨好

redis 塞对象 redis 对象列表_redis 塞对象_06

(2)dictht

不满足ziplist会被转化成dictht

redis 塞对象 redis 对象列表_redis_07

4.set对象(intset/ dictht)

(1)intset:整数

redis 塞对象 redis 对象列表_redis_08

(2)dictht:字符串(key为字符串对象,value=null)

不满足intset时会被转换

5.zset对象(ziplist/ 跳表+dict)

(1)ziplist

第一个节点保存member,第二个节点保存score;score从小到大排序

redis 塞对象 redis 对象列表_redis_09

(2)跳跃表+dict

跳跃表:主要用于范围型操作(ZRANK, ZRANGE)

dict:主要用于映射查找成员的score(ZCORE),复杂度O(1)

此外,同时用两个数据结构不会造成额外的空间浪费,因为都是通过指针来共享同一块内存区域

redis 塞对象 redis 对象列表_字符串_10