Redis學習筆記(六) 物件系統

2021-10-17 08:38:14 字數 4184 閱讀 9033

2. redis中的五種物件型別

2.2 列表物件

2.3 雜湊物件

2.4 集合物件

2.5 有序集合物件

3. 記憶體**機制

4. 物件共享機制

5. 物件的空轉時長

總結參考資料

redis沒有直接使用基礎資料結構來實現資料庫,而是基於這些資料結構建立了乙個物件系統。這個系統包含字串物件、列表物件、雜湊物件、集合物件、有序集合物件。

資料結構

應用場景

簡單動態字串

儲存字串值

鍊錶列表鍵,發布與訂閱,慢查詢,監視器

字典雜湊鍵,資料庫鍵空間

跳躍表有序集合鍵

整數集合

集合鍵壓縮列表

列表鍵、雜湊鍵

redis使用物件表示資料庫中的鍵和值,每次在redis新建乙個鍵值對都會建立兩個物件,鍵物件和值物件

redis中的每個物件由乙個struct redisobject結構表示:

// src/redis.h

typedef struct redisobject robj;

其中type屬性表示物件型別, encoding屬性表示物件編碼。以下介紹物件型別和物件編碼的概念。

2.1 物件型別

redis 3.0中,定義如下5種物件型別:

型別常量

物件名稱

type命令的輸出

redis_string

字串「string」

redis_list

列表「list」

redis_set

集合「set」

redis_zset

有序集合

「zset」

redis_hash

雜湊「hash」

注意,對於redis中的任一鍵值對,鍵總是乙個字串物件,而值可以是上面5種物件的任意一種。比如說,列表鍵的意思是指,這個鍵對應的值是列表物件,其他型別物件以此類推。

type命令用於返回物件型別。

2.2 物件編碼

redisobject中的ptr指標指向物件使用的基礎資料結構,而具體使用何種資料結構是由物件編碼決定的。

encoding屬性用於表示物件編碼,說明這個物件使用的是何種資料結構。redis 3.0中,encoding值可以是如下的任何一種:

encoding

使用的底層資料結構

redis_encoding_raw

sdsredis_encoding_int

long型別數

redis_encoding_ht

字典redis_encoding_linkedlist

雙端鍊錶

redis_encoding_ziplist

壓縮列表

redis_encoding_intset

整數集合

redis_encoding_skiplist

跳表redis_encoding_embstr

embstr編碼的sds

object encoding命令用於檢視某個資料庫鍵的值物件的編碼。

每種型別的物件都使用了至少兩種不同的編碼,這使得redis可以優化物件在不同場景下的效率和空間占用。

2.3 不同型別和編碼的物件

物件型別

可能的編碼型別

字串long, embstr,raw

列表壓縮列表、雙端鍊錶

雜湊壓縮列表、字典

集合整數集合、字典

有序集合

壓縮列表、跳表

2.1 字串物件

字串物件有三種編碼,可以是int, embstr, raw。使用何種編碼是通過字串物件儲存的值型別和字串長度決定,規則如下:

對應redis原始碼中createstringobject的實現:

#define redis_encoding_embstr_size_limit 39

robj *createstringobject(char *ptr, size_t len)

2.1.1 為什麼需要embstr編碼?

embstr編碼是專門為儲存短字串的一種優化編碼方式。和raw編碼區別在於,embstr編碼僅呼叫一次記憶體分配函式同時建立redisobject和sdshdr結構,優勢如下:

以下分別給出raw編碼和embstr編碼的字串物件示意圖:

raw編碼字串:

embstr編碼字串:

2.1.2 編碼的轉換

2.2 列表物件

列表物件編碼可以是ziplist或linkedlist,建立列表物件**如下:

robj *createlistobject(void);

robj *createziplistobject(void);

2.2.1 編碼的轉換

當列表物件同時滿足以下兩個條件時,列表物件使用ziplist編碼,否則使用linkedlist編碼

2.3 雜湊物件

雜湊物件編碼可以是ziplist或hashtable,建立物件**如下:

robj *

createhashobject

(void

);

2.3.1 編碼的轉換

當雜湊物件同時滿足以下兩個條件時,雜湊物件使用ziplist編碼,否則使用hashtable編碼

2.4 集合物件

集合物件編碼可以是intset或hashtable

2.4.1 編碼的轉換

當集合物件可以同時滿足以下兩個條件時,物件使用intset編碼,否則使用hashtable編碼

2.5 有序集合物件

有序集合物件編碼可以是ziplist或skiplist

基於skiplist編碼的資料結構如下,可以看到有序集合物件同時使用了跳表和字典資料結構來實現。

typedef struct zset  zset;
有序集合元素同時儲存在跳表和字典,示意圖如下:

圖中字典和跳表重複列出了各元素的成員和分數,而原始碼實現中,字典和跳表會共享元素的成員和分數,不會導致記憶體浪費。

2.5.1 為什麼有序集合需要同時使用跳躍表和字典來實現?

2.5.2 編碼的轉換

有序集合物件可以同時滿足以下兩個條件,物件使用ziplist編碼,否則使用skiplist編碼

redis是通過c語言實現的,c語言沒有記憶體自動**機制,因此redis在物件系統中通過引用計數方式實現記憶體**機制。

每個物件的引用計數資訊通過redisobject結構中的refcount屬性表示:

object refcount命令可以檢視物件的引用計數。

物件的refcount屬性除了用於實現記憶體**機制外,還具有共享記憶體的作用。

比如,redis伺服器啟動時會預先建立0 ~ 9999這1萬個字串物件。當redis需用到0 ~ 9999的字串物件時,直接使用共享物件,不必每次都建立新物件,從而節約記憶體。原始碼參考object.c/createstringobjectfromlonglong

// object.c

robj *createstringobjectfromlonglong(long long value) else

return o;

};

4.1 為什麼redis只共享包含整數的物件?

redisobject的lru屬性記錄物件最後一次被命令程式訪問的時間,可用於計算某個資料庫鍵的空轉時長。

object ldletime命令用於獲取物件的空轉時長,空轉時長是通過當前時間減去物件的lru值計算得出。

空轉時長可用於redis伺服器**記憶體演算法,原則是記憶體不足時,空轉時長高的鍵優先被伺服器釋放,**記憶體。

《redis設計與實現》 —— 第8章 物件

Redis學習筆記(六) 物件

前面我們看了redis用到的主要資料結構,如簡單動態字串 sds 雙向鍊錶 字典 壓縮列表 整數集合等。但是redis並沒有直接使用這些資料結構來實現鍵值對,而是基於這些資料結構建立了乙個物件系統,這個系統包括字串物件 列表物件 雜湊物件 集合物件 有序集合物件,除此之外,redis的物件系統還實現...

Redis筆記2 物件

redis中總共有五種型別的物件,分別是 字串物件 雙端鍊錶 字典 壓縮列表 整數集合。上述的五種型別的物件均具有相同的結構 typedef struct redisobject 物件的型別總共為五種,如下 可以通過 type 命令驗證 redis物件的型別 編碼決定了redis物件儲存過程中所採用...

PDF學習六 物件

說明 pdf支援8種基本型別物件。布林物件 數字物件 串物件 名稱物件 陣列物件 字典物件 流物件 空物件,以及間接物件。pdf reference1.7.pdf 3.2 objects 熟練掌握pdf8種基本型別物件。true false 整數物件 integer 以零為中心表示乙個特定間隔內的整...