共計 2558 個字符,預計需要花費 7 分鐘才能閱讀完成。
這篇文章主要介紹“redis 的 Object 結構體怎么定義”的相關知識,丸趣 TV 小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“redis 的 Object 結構體怎么定義”文章能幫助大家解決問題。
Redis 的兩層數據結構簡介
redis 的性能高的原因之一是它每種數據結構都是經過專門設計的,并都有一種或多種數據結構來支持,依賴這些靈活的數據結構,來提升讀取和寫入的性能。如果要了解 redis 的數據結構,可以從兩個不同的層面來討論它:
第一個層面,是從使用者的角度,這一層面也是 Redis 暴露給外部的調用接口,比如:string,list,hash,set,sorted set。
第二個層面,是從內部實現的角度,屬于更底層的實現,比如:dict,sds,ziplist,quicklist,skiplist,intset。
Redis 數據結構的內部實現
從 Redis 的使用者的角度來看,一個 Redis 節點包含多個 database(非 cluster 模式下默認是 16 個,cluster 模式下只能是 1 個),而一個 database 維護了從 key space 到 object space 的映射關系。這個映射關系的 key 是 string 類型,而 value 可以是多種數據類型,比如:string, list, hash、set、sorted set 等。我們可以看到,key 的類型固定是 string,而 value 可能的類型是多個。
而從 Redis 內部實現的角度來看,database 內的這個映射關系是用一個 dict 來維護的。dict 的 key 固定用一種數據結構來表達就夠了,這就是動態字符串 sds。而 value 則比較復雜,為了在同一個 dict 內能夠存儲不同類型的 value,這就需要一個通用的數據結構,這個通用的數據結構就是 robj,全名是 redisObject。
舉個例子:
如果 value 是一個 list,那么它的內部存儲結構是一個 quicklist。
如果 value 是一個 string,那么它的內部存儲結構一般情況下是一個 sds。但如果 string 類型的 value 的值是一個數字,那么 Redis 內部還會把它轉成 long 型來存儲,從而減小內存使用。
所以,一個 robj 既能表示一個 sds,也能表示一個 quicklist,甚至還能表示一個 long 型。
redisObject 結構體
redisObject 的定義如下:
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
int refcount;
void *ptr;} robj;
一個 robj 包含如下 5 個字段:
type: 對象的數據類型。占 4 個 bit。可能的取值有 5 種: OBJ_STRING, OBJ_LIST, OBJ_SET, OBJ_ZSET,
OBJ_HASH,分別對應 Redis 對外暴露的 5 種數據結構
encoding: 對象的內部表示方式(也可以稱為編碼),占 4 個 bit,可能的取值有 10 種。
lru: 做 LRU 替換算法用,占 24 個 bit。
refcount: 引用計數。它允許 robj 對象在某些情況下被共享。
ptr: 數據指針。指向真正的數據。比如,一個代表 string 的 robj,它的 ptr 可能指向一個 sds 結構;一個代表 list 的 robj,它的 ptr 可能指向一個 quicklist。
這里特別需要仔細察看的是 encoding 字段。對于同一個 type,還可能對應不同的 encoding,這說明同樣的一個數據類型,可能存在不同的內部表示方式。而不同的內部表示,在內存占用和查找性能上會有所不同。
當 type = OBJ_STRING 的時候,表示這個 robj 存儲的是一個 string,這時 encoding 可以是下面 3 種中的一種:
OBJ_ENCODING_RAW: string 采用原生的表示方式,即用 sds 來表示。
OBJ_ENCODING_INT: string 采用數字的表示方式,實際上是一個 long 型。
OBJ_ENCODING_EMBSTR: string 采用一種特殊的嵌入式的 sds 來表示。
當 type = OBJ_HASH 的時候,表示這個 robj 存儲的是一個 hash,這時 encoding 可以是下面 2 種中的一種:
OBJ_ENCODING_HT: hash 采用一個 dict 來表示。
OBJ_ENCODING_ZIPLIST: hash 采用一個 ziplist 來表示。
encoding 的十種取值如下:
OBJ_ENCODING_RAW: 最原生的表示方式。其實只有 string 類型才會用這個 encoding 值(表示成 sds)。
OBJ_ENCODING_INT: 表示成數字。實際用 long 表示。
OBJ_ENCODING_HT: 表示成 dict。
OBJ_ENCODING_ZIPMAP: 是個舊的表示方式,已不再用。在小于 Redis 2.6 的版本中才有。
OBJ_ENCODING_LINKEDLIST: 也是個舊的表示方式,已不再用。
OBJ_ENCODING_ZIPLIST: 表示成 ziplist。
OBJ_ENCODING_INTSET: 表示成 intset。用于 set 數據結構。
OBJ_ENCODING_SKIPLIST: 表示成 skiplist。用于 sorted set 數據結構。
OBJ_ENCODING_EMBSTR: 表示成一種特殊的嵌入式的 sds。
OBJ_ENCODING_QUICKLIST: 表示成 quicklist。用于 list 數據結構。
redisObject 的作用
redisObject 的作用的作用如下:
redisObjec 是聯結兩個層面的數據結構的橋梁。
為多種數據類型提供一種統一的表示方式。
允許同一類型的數據采用不同的內部表示,從而在某些情況下盡量節省內存。
支持對象共享和引用計數。當對象被共享的時候,只占用一份內存拷貝,進一步節省內存。
關于“redis 的 Object 結構體怎么定義”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注丸趣 TV 行業資訊頻道,丸趣 TV 小編每天都會為大家更新不同的知識點。