blog icon indicating copy to clipboard operation
blog copied to clipboard

Redis 中的对象表示

Open junnplus opened this issue 6 years ago • 2 comments

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;
}

junnplus avatar Feb 16 '19 10:02 junnplus

OBJ_ENCODING_QUICKLIST 就是指 OBJ_ENCODING_LINKEDLIST 或者 OBJ_ENCODING_ZIPLIST吧. 根据不同情况来选择, 不应该当做独自的一类?

kzinglzy avatar Jun 12 '19 04:06 kzinglzy

@kzinglzy 不是的,quicklist是一种实现 https://github.com/antirez/redis/blob/unstable/src/quicklist.c#L94

junnplus avatar Jun 14 '19 06:06 junnplus