redis學習筆記——資料類型

來源:互聯網
上載者:User

標籤:

對象處理機制

Redis 構建了自己的類型系統,這個系統的主要功能包括:
• redisObject 對象。
• 基於redisObject 對象的類型檢查。
• 基於redisObject 對象的顯式多態函數。
• 對redisObject 進行分配、共用和銷毀的機制。

(redisObject 實際上是只是一個結構類型。)

 

redisObject 的定義位於redis.h :
/*
* Redis 對象
*/
typedef struct redisObject {
// 類型
unsigned type:4;
// 對齊位
unsigned notused:2;
// 編碼方式
unsigned encoding:4;
// LRU 時間(相對於server.lruclock)
unsigned lru:22;
// 引用計數
int refcount;
// 指向對象的值
void *ptr;
} robj;

type 、encoding 和ptr 是最重要的三個屬性。

type 記錄了對象所儲存的值的類型,它的值可能是以下常量的其中一個(定義位於redis.h):

/*
* 物件類型
*/
#define REDIS_STRING 0 // 字串
#define REDIS_LIST 1 // 列表
#define REDIS_SET 2 // 集合
#define REDIS_ZSET 3 // 有序集
#define REDIS_HASH 4 // 雜湊表

encoding 記錄了對象所儲存的值的編碼,它的值可能是以下常量的其中一個(定義位於redis.h):

/*
* 對象編碼
*/
#define REDIS_ENCODING_RAW 0 // 編碼為字串
#define REDIS_ENCODING_INT 1 // 編碼為整數
#define REDIS_ENCODING_HT 2 // 編碼為雜湊表
#define REDIS_ENCODING_ZIPMAP 3 // 編碼為zipmap
#define REDIS_ENCODING_LINKEDLIST 4 // 編碼為雙端鏈表
#define REDIS_ENCODING_ZIPLIST 5 // 編碼為壓縮列表
#define REDIS_ENCODING_INTSET 6 // 編碼為整數集合
#define REDIS_ENCODING_SKIPLIST 7 // 編碼為跳躍表

ptr 是一個指標,指向實際儲存值的資料結構,這個資料結構由type 屬性和encoding 屬性決定。
舉個例子, 如果一個redisObject 的type 屬性為REDIS_LIST , encoding 屬性為REDIS_ENCODING_LINKEDLIST ,那麼這個對象就是一個Redis 列表,它的值儲存在一個雙端鏈表內,而ptr 指標就指向這個雙端鏈表;

命令的類型檢查和多態

當執行一個處理資料類型的命令時,Redis 執行以下步驟:
1. 根據給定key ,在資料庫字典中尋找和它像對應的redisObject ,如果沒找到,就返回NULL 。
2. 檢查redisObject 的type 屬性和執行命令所需的類型是否相符,如果不相符,傳回型別錯誤。
3. 根據redisObject 的encoding 屬性所指定的編碼,選擇合適的操作函數來處理底層的資料結構。
4. 返回資料結構的操作結果作為命令的傳回值。

對象共用

有一些對象在Redis 中非常常見,比如命令的傳回值OK 、ERROR 、WRONGTYPE 等字元,另外,一些小範圍的整數,比如個位、十位、百位的整數都非常常見。

為了利用這種常見情況,Redis 在內部使用了一個Flyweight 模式:通過預分配一些常見的值對象,並在多個資料結構之間共用這些對象,程式避免了重複分配的麻煩,也節約了一些CPU時間。

Redis 預分配的值對象有如下這些:
• 各種命令的傳回值,比如執行成功時返回的OK ,執行錯誤時返回的ERROR ,類型錯誤時返回的RONGTYPE ,命令入隊事務時返回的QUEUED ,等等。
• 包括0 在內, 小於redis.h/REDIS_SHARED_INTEGERS 的所有整數(REDIS_SHARED_INTEGERS 的預設值為10000)

Note: 共用對象只能被帶指標的資料結構使用。
需要提醒的一點是,共用對象只能被字典和雙端鏈表這類能帶有指標的資料結構使用。

像整數集合和壓縮列表這些只能儲存字串、整數等字面值的記憶體資料結構,就不能使用共用
對象。

引用計數以及對象的銷毀

Redis 的對象系統使用了引用計數技術來負責維持和銷毀對象,它的
運作機制如下:
• 每個redisObject 結構都帶有一個refcount 屬性,指示這個對象被引用了多少次。
• 當新建立一個對象時,它的refcount 屬性被設定為1 。
• 當對一個對象進行共用時,Redis 將這個對象的refcount 增一。
• 當使用完一個對象之後,或者取消對共用對象的引用之後,程式將對象的refcount 減一。
• 當對象的refcount 降至0 時,這個redisObject 結構,以及它所引用的資料結構的記憶體,都會被釋放。

字串

字串編碼

字串類型分別使用REDIS_ENCODING_INT 和REDIS_ENCODING_RAW 兩種編碼:
• REDIS_ENCODING_INT 使用long 類型來儲存long 類型值。
• REDIS_ENCODING_RAW 則使用sdshdr 結構來儲存sds (也即是char* )、long long 、double 和long double 類型值。

換句話來說,在Redis 中,只有能表示為long 類型的值,才會以整數的形式儲存,其他類型的整數、小數和字串,都是用sdshdr 結構來儲存。

編碼的選擇

新建立的字串預設使用REDIS_ENCODING_RAW 編碼,在將字串作為鍵或者值儲存進資料庫時,程式會嘗試將字串轉為REDIS_ENCODING_INT 編碼。

雜湊表

REDIS_HASH (雜湊表) 是HSET 、HLEN 等命令的操作對象, 它使用REDIS_ENCODING_ZIPLIST 和REDIS_ENCODING_HT 兩種編碼方式:

字典編碼的雜湊表

當雜湊表使用字典編碼時,程式將雜湊表的鍵(key)儲存為字典的鍵,將雜湊表的值(value)儲存為字典的值。

雜湊表所使用的字典的鍵和值都是字串對象。展示了一個包含三個索引值對的雜湊表:

壓縮列表編碼的雜湊表

當使用REDIS_ENCODING_ZIPLIST 編碼雜湊表時,程式通過將鍵和值一同推入壓縮列表,從而形成儲存雜湊表所需的鍵-值對結構:

新添加的key-value 對會被添加到壓縮列表的表尾。
當進行尋找/刪除或更新操作時,程式先定位到鍵的位置,然後再通過對鍵的位置來定位值的位置。

編碼的選擇

建立空白雜湊表時,程式預設使用REDIS_ENCODING_ZIPLIST 編碼,當以下任何一個條件被滿足時,程式將編碼從切換為REDIS_ENCODING_HT :
• 雜湊表中某個鍵或某個值的長度大於server.hash_max_ziplist_value (預設值為64)。
• 壓縮列表中的節點數量大於server.hash_max_ziplist_entries (預設值為512 )。

 

列表

REDIS_LIST (列表) 是LPUSH 、LRANGE 等命令的操作對象, 它使用REDIS_ENCODING_ZIPLIST 和REDIS_ENCODING_LINKEDLIST 這兩種方式編碼:

編碼的選擇

建立新列表時Redis 預設使用REDIS_ENCODING_ZIPLIST 編碼,當以下任意一個條件被滿足時,列表會被轉換成REDIS_ENCODING_LINKEDLIST 編碼:
• 試圖往列表新添加一個字串值, 且這個字串的長度超過server.list_max_ziplist_value (預設值為64 )。
• ziplist 包含的節點超過server.list_max_ziplist_entries (預設值為512 )。

阻塞

BLPOP 、BRPOP 和BRPOPLPUSH 三個命令都可能造成用戶端被阻塞,以下將這些命令統稱為列表的阻塞原語。
阻塞原語並不是一定會造成用戶端阻塞:
• 只有當這些命令被用於空列表時,它們才會阻塞用戶端。
• 如果被處理的列表不為空白的話,它們就執行無阻塞版本的LPOP 、RPOP 或RPOPLPUSH命令。

 

redis學習筆記——資料類型

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.