动态

详情 返回 返回

Redis數據結構一之對象的介紹及各版本對應實現 - 动态 详情

本文首發於公眾號:Hunter後端
原文鏈接:Redis數據結構一之對象的介紹及各版本對應實現

本篇筆記開始介紹 Redis 數據結構的底層實現。

當我們被問到 Redis 中有什麼數據結構,或者説數據類型,我們可能會説有字符串、列表、哈希、集合、有序集合。

其實這幾種數據類型在 Redis 中都由對象構成,而且是兩個對象,一個鍵對象,一個值對象。

在這些數據類型中,它們的鍵都是字符串對象,而值可以是前面説的字符串對象、列表對象、哈希對象、集合對象、有序集合對象中的一種,這個取決於鍵值對的數據類型。

而在 Redis 中,這些對象都有其更底層的實現方式,也就是説這一篇筆記我們要介紹的,更底層的數據結構,而且不同的 Redis 版本有不一樣的數據結構,最基礎的數據結構包括簡單動態字符串、字典、跳躍表、整數集合等,

接下來我們先介紹一下 Redis 中對象的構成,然後介紹一下不同 Redis 版本中每個對象所使用的的底層數據結構,之後再逐個介紹這些數據結構的實現原理,以下是本篇筆記的目錄:

  1. Redis 對象的介紹
  2. 不同版本的 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 中各個數據結構的底層結構,在下一篇筆記中我們將正式逐個介紹各個數據結構的底層實現。

如果想獲取更多相關文章,可掃碼關注閲讀:
image.png

user avatar vanve 头像 qishiwohendou 头像 kohler21 头像 daqianduan 头像 crossoverjie 头像 best_6455a509a2177 头像 gouguoyin 头像 liujiaxiaobao 头像 feixiangdemojing 头像 zlibrarynew 头像 voidzxl 头像 weiwudejiqimao 头像
点赞 19 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.