本文首發于公眾號:Hunter后端
原文鏈接:Redis資料結構一之物件的介紹及各版本對應實作
本篇筆記開始介紹 Redis 資料結構的底層實作,
當我們被問到 Redis 中有什么資料結構,或者說資料型別,我們可能會說有字串、串列、哈希、集合、有序集合,
其實這幾種資料型別在 Redis 中都由物件構成,而且是兩個物件,一個鍵物件,一個值物件,
在這些資料型別中,它們的鍵都是字串物件,而值可以是前面說的字串物件、串列物件、哈希物件、集合物件、有序集合物件中的一種,這個取決于鍵值對的資料型別,
而在 Redis 中,這些物件都有其更底層的實作方式,也就是說這一篇筆記我們要介紹的,更底層的資料結構,而且不同的 Redis 版本有不一樣的資料結構,最基礎的資料結構包括簡單動態字串、字典、跳躍表、整數集合等,
接下來我們先介紹一下 Redis 中物件的構成,然后介紹一下不同 Redis 版本中每個物件所使用的的底層資料結構,之后再逐個介紹這些資料結構的實作原理,以下是本篇筆記的目錄:
- Redis 物件的介紹
- 不同版本的 Redis 物件的資料結構
注意:本篇文章的主體框架內容是基于書籍《Redis設計與實作》進行描述的,部分過時內容都基于網上查詢的相應資料與最新版本進行了對齊,如有其他疏漏,還望指正,
1、Redis 物件的介紹
舉一個例子,當我們設定一個字串型別的資料:
set msg "hello world"
這樣,我們就創建了兩個物件,且兩個都是字串物件,因為鍵值對的 key 和 value 都是字串,
如果我們創建了一個串列資料,那么 key 是字串物件,而值 value 是串列物件,
在 Redis 中,每個物件都由一個 redisObject 結構來表示:
typedef struct redisObject{
//型別
unsigned type:4;
//編碼
unsigned encoding:4;
//指向底層實作資料結構的指標
void *ptr
//...
} robj;
type
在上面的結構中,type 指的是這個物件的型別,比如我們創建了一個串列資料,那么這個資料的 key 就是一個字串物件,由這個結構里的 type 來指定,這個資料的 value 就是一個串列物件,也是由 type 來進行指定區分,
但是,當我們想要知道一條資料的資料型別是字串、串列、哈希、集合、有序集合的哪一種時,我們常常是需要知道的這條資料的 value 的型別,一般也是指的 value 的型別,因為資料的 key 的型別總是字串物件,
一條資料的值物件型別的獲取我們可以用 TYPE 命令來操作:
TYPE msg
TYPE 型別的值輸出就是我們那五種型別:string、list、hash、set、zset
encoding
encoding 指的是這個物件底層資料結構使用的編碼,
一個物件在不同的情況下的編碼及底層資料結構可能是不一樣的,比如對于字串物件,它的編碼包括 int,embstr,raw 這三種,但后兩種的底層結構其實都是簡單動態字串(SDS),不過它們的底層使用方式略有不同,這個我們在下一節再介紹,
獲取物件的值的編碼使用 OBJECT ENCODING
命令:
OBJECT ENCODING msg
ptr
ptr 則是作為指標指向的是物件的底層資料結構地址,
上面這些查看物件底層編碼的命令,我們會在介紹完各個底層資料結構之后根據存盤的不同資料型別進行使用,
2、不同版本的 Redis 物件的資料結構
Redis 3.2 版本以前
在 Redis 3.2 版本以前,每個物件對應的編碼,及底層資料結構如下:
字串物件
編碼(OBJECT ENCODING輸出結果) | 底層資料結構 |
---|---|
int | 整數 |
embstr | embstr編碼的SDS |
raw | SDS |
串列物件
編碼(OBJECT ENCODING輸出結果) | 底層資料結構 |
---|---|
ziplist | 壓縮串列 |
linkedlist | 雙向鏈表 |
哈希物件
編碼(OBJECT ENCODING輸出結果) | 底層資料結構 |
---|---|
ziplist | 壓縮串列 |
hashtable | 字典 |
集合物件
編碼(OBJECT ENCODING輸出結果) | 底層資料結構 |
---|---|
intset | 整數集合 |
hashtable | 字典 |
有序集合物件
編碼(OBJECT ENCODING輸出結果) | 底層資料結構 |
---|---|
ziplist | 壓縮串列 |
skiplist | 跳躍表 |
Redis 3.2 版本
而在 3.2 版本,主要對串列物件的底層實作做了修改,由 quicklist 構成底層實作,quicklist 實際上是 linkedlist 和 ziplist 的混合結構,
串列物件
編碼(OBJECT ENCODING輸出結果) | 底層資料結構 |
---|---|
quicklist | 快速串列 |
Redis 5.1 之后版本
在 Redis 5.1 版本,引入了新的資料結構 listpack,6.x 版本作為過渡階段,并且在 7.0 版本,listpack 已經完全替換了 ziplist,成為了哈希物件、有序集合物件的底層資料結構的原有實作之一,更改如下:
哈希物件
編碼(OBJECT ENCODING輸出結果) | 底層資料結構 |
---|---|
listpack | listpack |
hashtable | 字典 |
有序集合物件
編碼(OBJECT ENCODING輸出結果) | 底層資料結構 |
---|---|
listpack | listpack |
skiplist | 跳躍表 |
而且 quicklist 也變成了 linkedlist 和 listpack 的混合結構
這一篇筆記只是作為一個引子,引入 Redis 中各個資料結構的底層結構,在下一篇筆記中我們將正式逐個介紹各個資料結構的底層實作,
如果想獲取更多后端相關文章,可掃碼關注閱讀:
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/552449.html
標籤:NoSQL
下一篇:返回列表