概述
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。