Redis5.0原始碼解析(六)----------Redis物件
阿新 • • 發佈:2018-12-11
基於Redis5.0
之前介紹了 Redis 用到的所有主要資料結構, 比如簡單動態字串(SDS)、雙端連結串列、字典、跳躍表、整數集合, 等等,但Redis 並沒有直接使用這些資料結構來實現鍵值對資料庫, 而是基於這些資料結構建立了一個物件系統, 這個系統包含字串物件、列表物件、雜湊物件、集合物件和有序集合物件這五種型別的物件, 每種物件都用到了至少一種我們前面所介紹的資料結構
物件的型別與編碼
Redis 使用物件來表示資料庫中的鍵和值, 每次當我們在 Redis 的資料庫中新建立一個鍵值對時, 我們至少會建立兩個物件, 一個物件用作鍵值對的鍵(鍵物件), 另一個物件用作鍵值對的值(值物件)
Redis 中的每個物件都由一個 redisObject 結構表示, 該結構中和儲存資料有關的三個屬性分別是 type
屬性、 encoding
屬性和 ptr
屬性:
//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
:儲存物件使用的資料型別,命令type {key}
返回值物件的資料型別encoding
:儲存物件使用的內部編碼型別,命令object encoding {key}
返回值物件的內部編碼型別lru
:記錄物件最後一次被訪問的時間(用於記憶體回收),命令object idletime {key}
檢視鍵的空閒時間,LRU/LFU
refcount
:記錄物件的引用計數(用於回收),命令object refcount {key}
檢視鍵的引用數ptr
型別
物件的 type
屬性記錄了物件的型別
//server.h
/*-----------------------------------------------------------------------------
* Data types
*----------------------------------------------------------------------------*/
/* 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. */
/* The "module" object type is a special one that signals that the object
* is one directly managed by a Redis module. In this case the value points
* to a moduleValue struct, which contains the object value (which is only
* handled by the module itself) and the RedisModuleType struct which lists
* function pointers in order to serialize, deserialize, AOF-rewrite and
* free the object.
*
* Inside the RDB file, module types are encoded as OBJ_MODULE followed
* by a 64 bit module type ID, which has a 54 bits module-specific signature
* in order to dispatch the loading to the right module, plus a 10 bits
* encoding version. */
#define OBJ_MODULE 5 /* Module object. */
#define OBJ_STREAM 6 /* Stream object. */
對於 Redis 資料庫儲存的鍵值對來說, 鍵總是一個字串物件, 而值則可以是字串物件、列表物件、雜湊物件、集合物件或者有序集合物件的其中一種
# 鍵為字串物件,值為字串物件
redis> SET msg "hello world"
OK
redis> TYPE msg
string
# 鍵為字串物件,值為列表物件
redis> RPUSH numbers 1 3 5
(integer) 6
redis> TYPE numbers
list
# 鍵為字串物件,值為雜湊物件
redis> HMSET profile name Tome age 25 career Programmer
OK
redis> TYPE profile
hash
# 鍵為字串物件,值為集合物件
redis> SADD fruits apple banana cherry
(integer) 3
redis> TYPE fruits
set
# 鍵為字串物件,值為有序集合物件
redis> ZADD price 8.5 apple 5.0 banana 6.0 cherry
(integer) 3
redis> TYPE price
zset
編碼
物件的 ptr
指標指向物件的底層實現資料結構, 而這些資料結構由物件的 encoding
屬性決定,encoding
屬性記錄了物件所使用的編碼, 也即是說這個物件使用了什麼資料結構作為物件的底層實現
//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 */
通過 encoding
屬性來設定物件所使用的編碼, 而不是為特定型別的物件關聯一種固定的編碼, 極大地提升了 Redis 的靈活性和效率, 因為 Redis 可以根據不同的使用場景來為一個物件設定不同的編碼, 從而優化物件在某一場景下的效率
redis> SET msg "hello wrold"
OK
redis> OBJECT ENCODING msg
"embstr"
redis> SET story "long long long long long long ago ..."
OK
redis> OBJECT ENCODING story
"raw"
redis> SADD numbers 1 3 5
(integer) 3
redis> OBJECT ENCODING numbers
"intset"
redis> SADD numbers "seven"
(integer) 1
redis> OBJECT ENCODING numbers
"hashtable"
接下來我們將分別介紹 Redis 中的五種不同型別的物件, 說明這些物件底層所使用的編碼方式
- 字串物件
- 列表物件
- 雜湊物件
- 集合物件
- 有序集合物件