Redis數據結構一之對象的介紹及各版本對應實現

来源:https://www.cnblogs.com/hunterxiong/archive/2023/05/14/17400433.html
-Advertisement-
Play Games

本文首發於公眾號:Hunter後端 原文鏈接:Redis數據結構一之對象的介紹及各版本對應實現 本篇筆記開始介紹 Redis 數據結構的底層實現。 當我們被問到 Redis 中有什麼數據結構,或者說數據類型,我們可能會說有字元串、列表、哈希、集合、有序集合。 其實這幾種數據類型在 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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 之前有個項目需要執行一個略微耗時的操作大概五六七八九十秒這樣子,這個時候程式不能做其他操作,只能等待操作完成。為了提升一絲使用體驗同時讓Winform程式看上去高級一點🎃🎃🎃,就想到加一個遮罩層(MaskLayer)。雖然Winform沒有原生的遮罩層,但是實現起來也不是很麻煩。 遮罩層 ...
  • 目錄 沁恆 CH32V208(一): CH32V208WBU6 評估板上手報告和Win10環境配置 沁恆 CH32V208(二): CH32V208的儲存結構, 啟動模式和時鐘 沁恆 CH32V208(三): CH32V208 Ubuntu22.04 Makefile VSCode環境配置 沁恆 C ...
  • 以 redhat7.4為例,網上的解決方案多是針對ubuntu的,需要進入ubuntu的預覽系統,redhat好像沒這個東西 問題:新添磁碟後開機無法進入系統。 似乎是因為電腦將新增的空硬碟作為了系統盤進行啟動,所以無法啟動系統。 解決方案:只要讓電腦將裝有linux系統的硬碟進行啟動就可以解決 ...
  • 切換 Windows 的系統語言 Windows 10 專業版 (1)點擊左下角開始菜單欄 --> 設置 --> 時間和語言 --> 語言。 (2)點擊添加語言,在彈出的列表框中,選擇你要安裝的語言。 (3)下載完語言包後,點擊 Windows 顯示語言下拉框,選擇剛剛安裝的語言。 (4)選擇新的語 ...
  • 定時器詳解 引出 定時器是一個比較常見的數據結構,或者說框架,以一個最簡單的例子引出,在游戲中,冷卻時間使用的就是定時器; 所以說定時器是**等待時間過期執行對應時間事件處理( 回調函數 )**的一個框架; 補充:下文中可能會出現定時任務,它和時間事件基本上是一個東西 那麼現在有一個就有一個問題,該 ...
  • Ubuntu下的串口軟體, 除了 CuteCOM, screen, MiniCOM 以外, 還有一個和 MiniCOM 很像的 PicoCOM. 最近在調試 CH340C 串口的過程中, 發現只有 PicoCOM 的連接Reset才能正常工作, 因此單獨記錄一下. ...
  • 這個問題弄了半天,希望可以幫到你。 首先報一下配置: DELL G15 2023 無線網卡:Intel AX201 BIOS版本為最新(截止到2023.5.15) 首先,打開終端ctrl+alt+T 然後,在終端鍵入: uname -r // 查看內核版本 // ax201 需要內核版本5.2+ / ...
  • 1. 查詢速度慢並不只是因為SQL語句本身,還可能是因為記憶體分配不佳、文件結構不合理等其他原因 1.1. 都是為了減少對硬碟的訪問 2. 不同代碼能夠得出相同結果 2.1. 從理論上來說,得到相同結果的不同代碼應該有相同的性能 2.2. 遺憾的是,查詢優化器生成的執行計劃很大程度上要受到代碼外部結構 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...