Redis设计了多种数据结构,并以此为基础构建了多种对象,每种对象(除了新出的 stream 以外)都有超过一种的实现。
redisObject 这个结构体反应了 Redis 对象的内存布局
typedef struct redisObject { unsigned type:4;//对象类型 unsigned encoding:4;//底层数据结构 unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or * LFU data (least significant 8 bits frequency * and most significant 16 bits access time). */ int refcount; void *ptr;//指向数据结构的指针 } robj;
可以看出,robj 用4个 bit 存储对象类型,4个 bit 存储对象的底层数据结构
其中对象类型有下面几种:
#define OBJ_STRING 0 /* String object. *///字符串类型 #define OBJ_LIST 1 /* List object. *///列表类型 #define OBJ_SET 2 /* Set object. *///集合对象 #define OBJ_ZSET 3 /* Sorted set object. *///有序集合对象 #define OBJ_HASH 4 /* Hash object. *///哈希对象 #define OBJ_MODULE 5 /* Module object. *///模块对象 #define OBJ_STREAM 6 /* Stream object. *///流对象,redis 5中新增
数据结构有下面几种:
#define OBJ_ENCODING_RAW 0 /* Raw representation *///基本 sds #define OBJ_ENCODING_INT 1 /* Encoded as integer *///整数表示的字符串 #define OBJ_ENCODING_HT 2 /* Encoded as hash table *///字典 #define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */ //废弃 #define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. *//废弃 #define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist *///压缩列表 #define OBJ_ENCODING_INTSET 6 /* Encoded as intset *///整数集合 #define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist *///跳跃表 #define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding *///embstr #define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */ #define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */
其实观察 objectComputeSize 这个方法就看出对象与数据结构的关联关系
OBJ_STRING = OBJ_ENCODING_RAW + OBJ_ENCODING_INT + OBJ_ENCODING_EMBSTR
OBJ_LIST = OBJ_ENCODING_QUICKLIST + OBJ_ENCODING_ZIPLIST
OBJ_SET = OBJ_ENCODING_INTSET + OBJ_ENCODING_HT
OBJ_ZSET = OBJ_ENCODING_SKIPLIST + OBJ_ENCODING_ZIPLIST
OBJ_HASH = OBJ_ENCODING_HT + OBJ_ENCODING_ZIPLIST
OBJ_STREAM = OBJ_ENCODING_STREAM