Redis的數據結構

概述

Redis作爲時下最流行的nosql數據庫,是開放打怪必備的中間件神器。本文將爲大家介紹在Redis各種數據是如何存儲的。
在Redis中存在各種數據結構,主要的幾種結構爲Dict、dictht、dictEntry、sds、redisObject。

  • 在Cluster模式下,一個Redis實例對應一個RedisDB(db0);
  • 一個RedisDB對應一個Dict;
  • 一個Dict對應2個Dictht,正常情況只用到ht[0];ht[1] 在Rehash時使用。
  • Dictht中主要的存儲結點的結構爲dictEntry,用於存儲數據,dictEntry保存着Redis的key和value
  • Redis的key對應的數據類型爲SDS,Redis的value對應的數據類型爲value

1. Dict

在RedisDB中,數據都是在Dict這樣的一個結構中進行存儲和管理的。

/* 字典結構定義 */
typedef struct dict { 
    dictType *type;  // 字典類型
    void *privdata;  // 私有數據
    dictht ht[2];    // 哈希表[兩個]
    long rehashidx;   // 記錄rehash 進度的標誌,值爲-1表示rehash未進行
    int iterators;   //  當前正在迭代的迭代器數
} dict;

結構示意圖:
在這裏插入圖片描述

2. Redis哈希表 dictht(dict hash table)

Redis的數據全部存儲在dictht中,Redis的Dict中存在兩個dictht,一個用來存儲數據,一個用來Rehash。

/* hash表結構定義 */
typedef struct dictht {
    dictEntry **table;   // 哈希表數組
    unsigned long size;  // 哈希表的大小
    unsigned long sizemask; // 哈希表大小掩碼
    unsigned long used;  // 哈希表現有節點的數量
} dictht; 

結構示意圖:
在這裏插入圖片描述

3. Redis哈希桶 dictEntry

dictEntry在Redis作爲一個基本的存儲單元,保存着Redis中全部類型的K-V數據。

typedef struct dictEntry {
    void *key;
    void *val;
    struct dictEntry *next;
} dictEntry;

結構示意圖
在這裏插入圖片描述

3.1 SDS Redis的key

/* Redis Key */
struct sdshdr {
    int len;
    int free;
    char buf[];
};

3.2 redisObject Redis的value

Redis的所有的value,不管是哪種類型的數據,都是一個redisObject。

/* Redis Value */
typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
                            * LFU data (least significant 8 bits frequency
                            * and most significant 16 bits access time). */
    int refcount;
    void *ptr;
} robj;

以下是對redisObject的各個字段的解釋。
1)type
type字段表示對象的類型,目前包括以下幾種:

/* The actual Redis Object */
#define OBJ_STRING 0    /* String object. */
#define OBJ_LIST 1      /* List object. */
#define OBJ_SET 2       /* Set object. */
#define OBJ_ZSET 3      /* Sorted set object. */
#define OBJ_HASH 4      /* Hash object. */

2)encoding
encoding表示對象的內部編碼,佔4個比特。
對於Redis支持的每種類型,都有至少兩種內部編碼,例如對於字符串,有int、embstr、raw三種編碼。通過encoding屬性,Redis可以根據不同的使用場景來爲對象設置不同的編碼,大大提高了Redis的靈活性和效率。
3)lru
lru記錄的是對象最後一次被命令程序訪問的時間。通過對比lru時間與當前時間,可以計算某個對象的空轉時間;object idletime命令可以顯示該空轉時間(單位是秒)。object idletime命令的一個特殊之處在於它不改變對象的lru值。
4)refcount
refcount記錄的是該對象被引用的次數,類型爲整型。refcount的作用,主要在於對象的引用計數和內存回收。當創建新對象時,refcount初始化爲1;當有新程序使用該對象時,refcount加1;當對象不再被一個新程序使用時,refcount減1;當refcount變爲0時,對象佔用的內存會被釋放。
5)ptr
ptr指針指向具體的數據,例如在執行命令set hello world,ptr指向包含字符串world的SDS。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章