Redis中的物件
阿新 • • 發佈:2020-07-12
Redis中的每個物件都由一個redisObject
結構表示,該結構中和儲存資料有關的三個屬性分別是type
、encoding
和ptr
:
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;
1. 型別
Redis一共有5種類型,其中鍵值總是一個字串物件,而值可以是5中型別中的任意一種。可以通過TYPE命令來檢視鍵對應的值的型別
# 鍵為字串物件,值為字串物件
redis> SET msg "hello world"
OK
redis> TYPE msg
string
# 鍵為字串物件,值為列表物件
redis> RPUSH numbers 1 3 5
(integer)6
redis> TYPE numbers
list
不同型別值物件的TYPE命令輸出
物件型別 | 物件type屬性值 | TYPE命令的輸出 |
---|---|---|
字串 | REDIS_STRING |
"string" |
列表 | REDIS_LIST |
"list" |
雜湊 | REDIS_HASH |
"hash" |
集合 | REDIS_SET |
"set" |
有序集合 | REDIS_ZSET |
"zset" |
2. 編碼
物件的ptr
指標指向物件的底層實現資料結構,而這些資料結構由物件的encoding
屬性決定
redis> SET msg "hello world" OK redis> OBJECT ENCODING msg "embstr" // msg為embstr型別 redis> SET story "long long long long long long long ago ..." OK redis> OBJECT ENCODING msg "raw" // msg從embstr型別變成raw型別 redis> SADD numbers 1 3 5 (integer)3 redis> OBJECT ENCODING numbers "intset" // numbers為intset型別 redis> SADD numbers "seven" (integer)1 redis> OBJECT ENCODING numbers "hashtable" // numbers從intset型別變成hashtable型別
不同型別和編碼的物件
型別 | 編碼常量 | 底層資料結構 |
---|---|---|
REDIS_STRING |
REDIS_ENCODING_INT |
整數 |
REDIS_STRING |
REDIS_ENCODING_IEMBSTR |
embstr 編碼的簡單動態字串 |
REDIS_STRING |
REDIS_ENCODING_RAW |
簡單動態字串 |
REDIS_LIST |
REDIS_ENCODING_ZIPLIST |
壓縮列表 |
REDIS_LIST |
REDIS_ENCODING_LINKEDLIST |
雙端連結串列 |
REDIS_HASH |
REDIS_ENCODING_ZIPLIST |
壓縮列表 |
REDIS_HASH |
REDIS_ENCODING_HT |
字典 |
REDIS_SET |
REDIS_ENCODING_INTSET |
整數集合 |
REDIS_SET |
REDIS_ENCODING_HT |
字典 |
REDIS_ZSET |
REDIS_ENCODING_ZIPLIST |
壓縮列表 |
REDIS_ZSET |
REDIS_ENCODING_SKIPLIST |
跳躍表 |
OBJECT ENCODING對不同型別編碼的輸出
編碼常量 | OBJECT ENCODING命令輸出 |
---|---|
REDIS_ENCODING_INT |
"int" |
REDIS_ENCODING_IEMBSTR |
"embstr" |
REDIS_ENCODING_RAW |
"raw" |
REDIS_ENCODING_HT |
"hashtable" |
REDIS_ENCODING_LINKEDLIST |
"linkedlist" |
REDIS_ENCODING_ZIPLIST |
"ziplist" |
REDIS_ENCODING_INTSET |
"intset" |
REDIS_ENCODING_SKIPLIST |
"skiplist" |
3. 物件底層資料結構
在Redis中為了節省空間,物件的編碼是會發生轉化,底層的資料結構也會隨著發生變化。
-
字串物件編碼的轉換規則
- 如果一個字串物件儲存的是整數值,並且這個值可以用
long
型別來表示,那麼字串物件會將整數值儲存在物件結構ptr
屬性裡面,並將字串物件的屬性設定為int
- 如果字串物件儲存的是一個字串值,並且長度小於
39
位元組,那麼字串物件將使用embstr
編碼 - 對於
int
編碼的字串物件來說,如果將值修改成字串,那麼字串物件的編碼將從int
變為raw
- 對於
embstr
編碼的字串物件來說,如果字串的長度大於39
位元組,那麼字串物件的編碼將從embstr
變為raw
- 如果一個字串物件儲存的是整數值,並且這個值可以用
-
列表物件編碼的轉換規則
- 當列表物件儲存的所有字串元素的長度都小於
64
位元組,並且儲存的元素數量小於512
個,物件將使用ziplist
編碼 - 如果物件不滿足
ziplist
編碼的條件,物件將使用linkedlist
編碼
- 當列表物件儲存的所有字串元素的長度都小於
-
雜湊物件編碼的轉換規則
- 當雜湊物件儲存的所有鍵和值的字串長度都小於
64
位元組,並且鍵值對數量小於512
個,物件將使用ziplist
編碼 - 如果物件不滿足
ziplist
編碼的條件,物件將使用hashtable
編碼
- 當雜湊物件儲存的所有鍵和值的字串長度都小於
-
集合物件編碼的轉換規則
- 當集合物件儲存的所有元素都是整數值,並且元素數量小於
512
個,物件將使用inset
編碼 - 如果物件不滿足
inset
編碼的條件,物件將使用hashtable
編碼
- 當集合物件儲存的所有元素都是整數值,並且元素數量小於
-
有序集合物件編碼的轉換規則
- 當集合物件中儲存的元素數量小於
128
個,並且所有元素成員的長度都小於64
位元組,物件將使用ziplist
編碼 - 如果物件不滿足
ziplist
編碼的條件,物件將使用skiplist
編碼
- 當集合物件中儲存的元素數量小於
4. 物件型別檢查、回收、共享和空轉時長
-
伺服器在執行某些命令之前,會先檢查給定鍵的型別能否執行指定的命令,而檢查一個鍵的型別就是檢查鍵的值物件的型別
-
Redis的物件帶有引用計數實現的記憶體回收機制,當一個物件不再被使用時,該物件鎖佔用的記憶體就會被自動釋放
-
Redis會自動共享值為0~9999的字串物件
-
每個物件會記錄自己的最後一次被訪問的時間,這個時間可以用於計算物件的空轉時間。當回收演算法為
volatile-lru
或者allkeys-lru
,那麼當伺服器佔用的記憶體超過了maxmemory
選項所設定的上限時,空轉時間較高的那部分鍵會被伺服器優先釋放,從而回收記憶體