您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。