问:redis的debug object命令算出来的serializedlength是如何算出的?git
解答:github
见redis源码中的debug.c 函数 void debugCommand(redisClient *c) 的这一段代码:redis
off_t rdbSavedObjectLen(robj *o)函数见rdb.c:函数
int rdbSaveObject(rio *rdb, robj *o) 的返回值即为 serializedlength。编码
int rdbSaveObject(rio *rdb, robj *o) 函数见rdb.c: 代码太多,见:https://github.com/miaoyc1989/redis-3.0-annotated/blob/unstable/src/rdb.cspa
简单来讲,在rdbSaveObject函数中,redis会根据传入的对象数据类型调用相关的函数去计算对象占用的空间字节数。debug
数据类型与计算所需空间函数的对应关系以下表:3d
短结构 | 长结构 | |
REDIS_LIST | ziplistBlobLen(返回整个ziplist占用的内存字节数)、 rdbSaveRawString(函数返回保存字符串所需的空间字节数)ip |
rdbSaveLen(写入成功返回保存编码后的 len 所需的字节数)、 listRewind、listNext、listNodeValue(以上三个函数用于遍历列表项)、 rdbSaveStringObject (函数返回rdb保存字符串对象所需的字节数) |
REDIS_SET | intsetBlobLen(返回整数集合如今占用的字节总数量)、 rdbSaveRawString |
rdbSaveLen、 dictNext、dictGetKey(以上两个函数用于遍历集合成员)、 rdbSaveStringObject |
REDIS_ZSET | ziplistBlobLen、rdbSaveRawString | rdbSaveLen、 dictNext、dictGetKey、dictGetVal(以上三个函数用于遍历有序集合) rdbSaveStringObject、rdbSaveDoubleValue(返回值为int) |
REDIS_HASH | ziplistBlobLen、rdbSaveRawString | rdbSaveLen、 dictNext、dictGetKey、dictGetVal(以上三个函数用于迭代字典)、 rdbSaveStringObject |
REDIS_STRING | rdbSaveStringObject |
上面对逻辑的描述不够清晰,想要知道具体细节,仍是须要去看源码。
附表:
redis中几种数据类型的短结构和长结构编码对应关系:
短结构 | 长结构 | |
list | ziplist | linkedlist |
hash | ziplist | hashtable |
set | intset | hashtable |
zset | ziplist | skiplist |