RedisObject
redis所有类型,key都是sds存储,value都是对应redisOjbect
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
-
值类型(string、list、set、hash、zset),占用4个bit
代码中定义:
/* 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. */
-
encoding
-
编码类型,值实际使用的数据结构,占用4个bit
代码中定义:
#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 */
-
lru
- 数据最近访问时间,24个bit refcount
- 引用次数(值被引用的次数),4个bit ptr
- 指针,指向真实数据结构,8个bit
不同类型,用到的数据结构
类型 | 数据结构 | 含义 |
string | int | 值是整数类型 |
embstr | 简单字符串(44个字节以内包含),连续的内存空间,内存一次访问 加上redisObject其他字段,正好64byte,内存每次读取64byte | |
raw | sds字符串,与redisObject不是连续空间 | |
list | quicklist | 双端链表+ziplist |
hash | ziplist | ziplist实现hash |
hashtable | 元素个数超过512或值长度超过65byte,改用hashtable | |
set | intset | 整数集合 |
hashtable | 存的值不是int或超过512个,转为hashtable存储 | |
zset | ziplist | ziplist结构实现zset |
skiplist | skiplist+dict实现zset(元素超过128个或值大于64byte时转) |
扩展(字符串embstr)
当使用字符串类型时,如果值的长度小于44位时,会使用embstr类型数据结构,优点是所属redisObject,共占用64byte,为内存一次读取大小,可一次获取,所以内存读取快
object.c源码
#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
robj *createStringObject(const char *ptr, size_t len) {
if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT)
return createEmbeddedStringObject(ptr,len);
else
return createRawStringObject(ptr,len);
}
如上源码,当小于等于44时,创建embstr对象,否则创建raw对象
44长度计算公式:
-
redisOjbect占用
- 字段:type(4bit)+encoding(4bit)+lru(8bit+16bit)+refcount(4byte)+ptr(8byte)
- 换算:4bit+4bit+8bit+16bit+4byte+8byte=16byte sds占用
- 字段:uint8_t len(1 byte)+uint8_t alloc(1byte)+flags(1byte)+1byte(\n结尾自动拼接)
- 换算:1byte+1byte+1byte+1byte = 4byte sds中buf[]可存字节
- 64-16-4=44byte