問: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 |