# Redis字典知識點有哪些
## 一、Redis字典概述
### 1.1 字典在Redis中的地位
Redis字典(Dict)是Redis數據庫的核心數據結構之一,承擔著:
- 所有鍵值對的存儲(DB模塊)
- 哈希鍵的底層實現(Hash類型)
- 集合鍵的底層實現(Set類型)
- 有序集合鍵的部分實現(ZSet的value-score映射)
### 1.2 字典的特性
- **高性能查找**:平均O(1)時間復雜度
- **動態擴容**:自動處理哈希沖突和擴容
- **漸進式rehash**:避免大字典擴容時的服務停頓
- **多態設計**:支持不同類型的鍵值對
## 二、字典數據結構詳解
### 2.1 核心結構定義
```c
// 哈希表節點
typedef struct dictEntry {
void *key; // 鍵
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v; // 值(多類型支持)
struct dictEntry *next; // 形成鏈表
} dictEntry;
// 哈希表
typedef struct dictht {
dictEntry **table; // 哈希表數組
unsigned long size; // 哈希表大小
unsigned long sizemask; // 大小掩碼(=size-1)
unsigned long used; // 已使用節點數
} dictht;
// 字典
typedef struct dict {
dictType *type; // 類型特定函數
void *privdata; // 私有數據
dictht ht[2]; // 兩個哈希表(用于rehash)
long rehashidx; // rehash進度(-1表示未進行)
int16_t pauserehash; // rehash暫停標志
} dict;
ht[0]
和ht[1]
配合實現漸進式rehashdictEntry->next
解決哈希沖突dictType
結構包含多個函數指針,實現不同類型鍵值對的操作// 默認字符串哈希算法(siphash)
uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k);
// 整數鍵直接使用
dict->type->hashFunction(key);
操作類型 | 觸發條件 | 變化幅度 |
---|---|---|
擴容 | used/size > 1 (無BGSAVE) | 第一個≥used×2的2^n |
擴容 | used/size > 5 (有BGSAVE) | 同上 |
縮容 | used/size < 0.1 | 第一個≥used的2^n |
ht[1]
分配空間rehashidx=0
(表示開始rehash)ht[0]->table[rehashidx]
的整個桶rehashidx++
直到所有桶遷移完成// databasesCron()中調用
int dictRehashMilliseconds(dict *d, int ms) {
long long start = timeInMilliseconds();
int rehashes = 0;
while(dictRehash(d,100)) { // 每次遷移100個桶
rehashes += 100;
if (timeInMilliseconds()-start > ms) break;
}
return rehashes;
}
操作 | 平均復雜度 | 最壞復雜度 |
---|---|---|
查找 | O(1) | O(n) |
插入 | O(1) | O(n) |
刪除 | O(1) | O(n) |
擴容 | O(n) | O(n) |
// 查找鍵值對
dictEntry *dictFind(dict *d, const void *key) {
if (dictIsRehashing(d)) _dictRehashStep(d);
// 計算哈希值
h = dictHashKey(d, key);
for (table = 0; table <= 1; table++) {
idx = h & d->ht[table].sizemask;
he = d->ht[table].table[idx];
while(he) {
if (dictCompareKeys(d, key, he->key))
return he;
he = he->next;
}
if (!dictIsRehashing(d)) return NULL;
}
return NULL;
}
typedef struct dictIterator {
dict *d; // 被迭代的字典
long index; // 當前迭代的哈希表索引
int table, safe; // 哈希表編號和安全標志
dictEntry *entry, *nextEntry; // 當前節點和下一個節點
long long fingerprint; // 迭代器指紋(校驗用)
} dictIterator;
unsigned long dictScan(dict *d, unsigned long v,
dictScanFunction *fn,
void *privdata) {
// 使用高位順序掃描避免重復/遺漏
do {
// 處理當前桶
de = ht->table[v & m0];
while (de) {
fn(privdata, de);
de = de->next;
}
// 計算下一個掃描位置
v = ((v | m0) + 1) & ~m0 | (v & (m0 >> 1));
} while (v != 0);
}
dict_capacity[dict_capacity_size]
序列增長# Redis INFO命令輸出
redis-cli info stats | grep -E 'expired_stale_perc|evicted_keys|rehash'
# 使用哈希存儲用戶信息
HSET user:1001 name "張三" age 28 last_login 1630000000
# 統計頁面PV
HINCRBY page_views /home 1
避免一次性遷移大量數據導致服務停頓,保證Redis的高可用性。
理論最大容量為2^64個元素,但實際受內存限制。
Redis默認使用siphash算法,能有效防止碰撞攻擊。
本文總結了Redis字典的核心知識點,實際應用中還需結合具體場景進行調整。建議通過閱讀
src/dict.c
源碼加深理解。 “`
注:本文實際約2600字(中文字符統計標準),完整展示了Redis字典的實現原理、關鍵算法和最佳實踐。如需擴展特定部分,可以進一步補充實際案例或性能測試數據。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。