errorbeep@home:~$

Redis对象存储方式


在 Redis 中所有的数据类型都是将对应的数据结构进行了再一次包装,创建了一个字典对象来存储。每次创建一个key-value 键值对,Redis 都会创建两个对象,一个是键对象,一个是值对象。而且需要注意的是在 Redis 中,值对象并不是直接存储,而是被包装成 redisObject 对象,并同时将键对象和值对象通过 dictEntry 对象进行封装,如下就是一个 dictEntry 对象:

typedef struct dictEntry {
    void *key;//指向key,即sds
    union {
        void *val;//指向value
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;//指向下一个key-value键值对(哈希值相同的键值对会形成一个链表,从而解决哈希冲突问题)
} dictEntry;

redisObject 对象的定义为:

typedef struct redisObject {
    unsigned type:4;//对象类型(4位=0.5字节)
    unsigned encoding:4;//编码(4位=0.5字节)
    unsigned lru:LRU_BITS;//记录对象最后一次被应用程序访问的时间(24位=3字节)
    int refcount;//引用计数。等于0时表示可以被垃圾回收(32位=4字节)
    void *ptr;//指向底层实际的数据存储结构,如:sds等(8字节)
} robj;

Redis通过type和encoding这两个属性来识别当前的value 到底属于哪一种基本数据类型,以及当前数据类型的底层采用了何种数据结构进行存储。 当我们在 Redis 客户端中执行命令 set name sea-wolf,就会得到下图所示的一个结构(省略了部分属性):