Redis字典知识点有哪些

发布时间:2021-12-27 16:44:38 作者:iii
来源:亿速云 阅读:125
# 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;

2.2 关键设计解析

  1. 双哈希表设计ht[0]ht[1]配合实现渐进式rehash
  2. 链地址法:通过dictEntry->next解决哈希冲突
  3. 多态支持dictType结构包含多个函数指针,实现不同类型键值对的操作

三、哈希算法与冲突解决

3.1 Redis哈希算法

// 默认字符串哈希算法(siphash)
uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k);

// 整数键直接使用
dict->type->hashFunction(key);

3.2 哈希冲突处理

3.3 扩容/缩容条件

操作类型 触发条件 变化幅度
扩容 used/size > 1 (无BGSAVE) 第一个≥used×2的2^n
扩容 used/size > 5 (有BGSAVE) 同上
缩容 used/size < 0.1 第一个≥used的2^n

四、渐进式rehash机制

4.1 基本流程

  1. ht[1]分配空间
  2. 设置rehashidx=0(表示开始rehash)
  3. 每次字典操作时迁移ht[0]->table[rehashidx]的整个桶
  4. rehashidx++直到所有桶迁移完成

4.2 操作期间的访问规则

4.3 定时任务辅助迁移

// 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;
}

五、字典API实现原理

5.1 关键操作时间复杂度

操作 平均复杂度 最坏复杂度
查找 O(1) O(n)
插入 O(1) O(n)
删除 O(1) O(n)
扩容 O(n) O(n)

5.2 核心API解析

// 查找键值对
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;
}

六、字典的迭代与扫描

6.1 安全迭代器

typedef struct dictIterator {
    dict *d;                  // 被迭代的字典
    long index;               // 当前迭代的哈希表索引
    int table, safe;          // 哈希表编号和安全标志
    dictEntry *entry, *nextEntry; // 当前节点和下一个节点
    long long fingerprint;    // 迭代器指纹(校验用)
} dictIterator;

6.2 SCAN命令实现

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);
}

七、内存优化技巧

7.1 哈希表大小选择

7.2 内存回收策略

八、性能调优实践

8.1 监控指标

# Redis INFO命令输出
redis-cli info stats | grep -E 'expired_stale_perc|evicted_keys|rehash'

8.2 优化建议

  1. 避免大Key:单个哈希表元素不超过1MB
  2. 合理设置初始大小:预估元素数量避免频繁rehash
  3. 监控rehash状态:长时间rehash可能影响性能

九、典型应用场景

9.1 用户会话存储

# 使用哈希存储用户信息
HSET user:1001 name "张三" age 28 last_login 1630000000

9.2 实时计数器

# 统计页面PV
HINCRBY page_views /home 1

十、常见问题解答

Q1:为什么Redis使用渐进式rehash?

避免一次性迁移大量数据导致服务停顿,保证Redis的高可用性。

Q2:字典的最大容量是多少?

理论最大容量为2^64个元素,但实际受内存限制。

Q3:如何避免哈希碰撞攻击?

Redis默认使用siphash算法,能有效防止碰撞攻击。


本文总结了Redis字典的核心知识点,实际应用中还需结合具体场景进行调整。建议通过阅读src/dict.c源码加深理解。 “`

注:本文实际约2600字(中文字符统计标准),完整展示了Redis字典的实现原理、关键算法和最佳实践。如需扩展特定部分,可以进一步补充实际案例或性能测试数据。

推荐阅读:
  1. 使用Redis的相关知识点有哪些
  2. Redis面试知识点有哪些

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

redis

上一篇:Reddit广告服务系统是怎么构建的

下一篇:如何进行Oracle ERP系统月结与年结流程的探讨

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》