blog
blog copied to clipboard
Redis 中的对象表示
Redis 中的每个对象都由一个 redisObject 结构来表示:
// 5.0.3/src/server.h
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;
type(4 bit): 每个对象都有不同的类型。encoding(4 bit): 每个对象使用的数据结构作为底层实现。lru(24 bit): 记录对象的 LRU 信息。refcount(32 bit): 引用计数。ptr(8 byte): 指向底层数据结构的指针。
一个 redisObject 对象头结构在64位系统中占据 16 byte 的空间。
类型常量
// 5.0.3/src/server.h
/* A redis object, that is a type able to hold a string / list / set */
/* The actual Redis Object */
#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. */
编码常量
// 5.0.3/src/server.h
/* Objects encoding. Some kind of objects like Strings and Hashes can be
* internally represented in multiple ways. The 'encoding' field of the object
* is set to one of this fields for this object. */
#define OBJ_ENCODING_RAW 0 /* Raw representation */
#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 */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */
不同类型和编码的对象
| 类型常量 | 编码常量 | 对象 |
|---|---|---|
| OBJ_STRING | OBJ_ENCODING_INT | 使用整数值实现的字符串对象 |
| OBJ_STRING | OBJ_ENCODING_EMBSTR | 使用 embstr 编码的简单动态字符串实现的字符串对象 |
| OBJ_STRING | OBJ_ENCODING_RAW | 使用简单动态字符串实现的字符串对象 |
| OBJ_LIST | OBJ_ENCODING_ZIPLIST | 使用压缩列表实现的列表对象 |
| OBJ_LIST | OBJ_ENCODING_LINKEDLIST | 使用双端链表实现的列表对象 |
| OBJ_LIST | OBJ_ENCODING_QUICKLIST | 使用快速列表实现的列表对象 |
| OBJ_HASH | OBJ_ENCODING_ZIPLIST | 使用压缩列表实现的哈希对象 |
| OBJ_HASH | OBJ_ENCODING_HT | 使用字典实现的哈希对象 |
| OBJ_SET | OBJ_ENCODING_INTSET | 使用整数集合实现的集合对象 |
| OBJ_SET | OBJ_ENCODING_HT | 使用字典实现的集合对象 |
| OBJ_ZSET | OBJ_ENCODING_ZIPLIST | 使用压缩列表实现的有序集合对象 |
| OBJ_ZSET | OBJ_ENCODING_SKIPLIST | 使用跳跃表和字典实现的有序集合对象 |
| OBJ_STREAM | OBJ_ENCODING_STREAM | 使用基数树和紧凑列表实现的流对象 |
创建对象
// 5.0.3/src/object.c
robj *createObject(int type, void *ptr) {
robj *o = zmalloc(sizeof(*o));
o->type = type;
o->encoding = OBJ_ENCODING_RAW;
o->ptr = ptr;
o->refcount = 1;
...
return o;
}
OBJ_ENCODING_QUICKLIST 就是指 OBJ_ENCODING_LINKEDLIST 或者 OBJ_ENCODING_ZIPLIST吧. 根据不同情况来选择, 不应该当做独自的一类?
@kzinglzy 不是的,quicklist是一种实现 https://github.com/antirez/redis/blob/unstable/src/quicklist.c#L94