redis--dict rehash

一、Dict 整体结构

Redis 底层字典 Dict,用来实现 K-V 映射,是 Redis 核心底层结构,数组 + 单向链表(链地址法解决哈希冲突),由 3 个结构体组成:

  1. dict(字典主体)

    typedef struct dict {
    dictType *type; // 哈希函数类型
    void *privdata; // 私有参数
    dictht ht[2]; // 两个哈希表:ht[0]正常使用;ht[1]仅rehash时用
    long rehashidx; // rehash进度,-1代表不在rehash
    int16_t pauserehash; // rehash暂停标记,1暂停、0继续
    } dict;

  2. dictht(哈希表)

    typedef struct dictht {
    dictEntry **table; // entry指针数组
    unsigned long size; // 数组容量,永远是2的n次方
    unsigned long sizemask;// 掩码 = size -1,用来计算下标 hash & sizemask
    unsigned long used; // 现存键值对数量
    } dictht;

  3. dictEntry(哈希节点)

    typedef struct dictEntry {
    void *key; // key
    union { // value共用体,节省内存
    void *val;
    uint64_t u64;
    int64_t s64;
    double d;
    } v;
    struct dictEntry *next;// 链表指针,处理哈希冲突
    } dictEntry;

寻址规则:key 算出 hash 值,hash & sizemask 得到数组下标;哈希冲突时,挂在单链表后面。

二、Dict 扩容(触发条件)

负载因子:LoadFactor = used / size,新增 key 的时候检查:

  1. LoadFactor >=1,并且没有 BGSAVE/BGREWRITEAOF 后台进程,触发扩容;
  2. LoadFactor >5,强制扩容,不管有没有后台进程。

扩容新容量:取第一个 ≥ used+1 的 2 的 n 次方。

三、Dict 收缩(缩容)

删除元素后检查负载因子,LoadFactor < 0.1 ,触发哈希表收缩。 缩容新容量:取第一个 ≥ used 的 2 的 n 次方,最小不低于 4。

缩容也不能在 BGSAVE/BGREWRITEAOF、正在 rehash 时执行。

四、渐进式 rehash(核心面试重点)

目的:一次性迁移百万级数据会阻塞 Redis 主线程,所以分多次慢慢迁移,叫渐进式 rehash

完整流程

  1. 根据扩容 / 收缩,计算新哈希表 size,开辟内存给ht[1];
  2. rehashidx = 0,标记开始 rehash;
  3. 每次执行增、查、改、删命令时,顺带迁移 ht 0rehashidx 整条链表到 ht 1,rehashidx 自增;
  4. rehash 过程读写规则:
    • ✅ 新增 key:直接写入 ht 1,保证 ht 0 数据只减不增;
    • ✅ 查询 / 修改 / 删除:先查 ht 0,找不到再查 ht 1;
  5. 全部迁移完成:ht[1]赋值给ht[0],清空ht[1],释放旧 ht 0 内存;
  6. rehashidx = -1,rehash 结束。
相关推荐
加宝的起点雷达24 分钟前
40 条候选里 38 条来自同一个源,主卡整屏重样
人工智能·算法·创业
秋天的怀念_David31 分钟前
算法一千零一夜 · 第二十六夜 协议的母语
java·spring boot·算法
闻缺陷则喜何志丹3 小时前
【C++特性】四种类型转
c++·算法·类型转换
喵本喵叁肆3 小时前
用 Boosting 把弱隐私算法炼成强隐私算法(英文原题:Boosting and Differential Privacy (FOCS 2010))
算法·集成学习·boosting
青梅味猪大肠4 小时前
【操作系统-60】临近适应算法
java·linux·开发语言·嵌入式硬件·算法·操作系统
其实防守也摸鱼19 小时前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
Nuanyt19 小时前
LeetCode Hot 100 链表专题(五)· 2 题(Java)
java·算法·leetcode·链表
w_zero_one1 天前
递归算法(一)
java·开发语言·算法