Redis面试系列:Redis到底什么时候rehash?源码解析(二)

本文深入解析Redis字典的rehash操作,包括何时触发rehash、如何扩容和缩容,以及主动和懒惰rehash策略。Redis通过监控负载因子调整哈希表大小,保证数据结构性能。
摘要由CSDN通过智能技术生成
前言

上一章把Redis基础类型介绍完了,更深的问题便会问:哈希表会有什么缺点?或者你了解hash吗?它是怎么解决冲突的?Redis渐进式rehash的原理是什么?
下面就来深入的解析这些问题。

一、字典

字典是Redis中存在最广泛的一种数据结构不仅在哈希对象,集合对象和有序结合对象中都有使用,而且Redis所有的Key,Value都是存在db->dict这张字典中的。

Redis 的字典使用哈希表作为底层实现。

typedef struct dict {
   
    dictType *type;
    void *privdata;
    dictht ht[2];   // 包含一堆 dictEntry 即下面的结构体
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    unsigned long iterators; /* number of iterators currently running */
} dict;

typedef struct dictEntry {
   
    void *key;
    union {
   
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    // Redis 的哈希表使用链地址法(separate chaining)来解决键冲突:
    // 每个哈希表节点都有一个 next 指针, 多个哈希表节点可以用 next 指针构成一个单向链表,
    // 被分配到同一个索引上的多个节点可以用这个单向链表连接起来, 这就解决了键冲突的问题。
    struct dictEntry *next;
} dictEntry;

// 这2个结构体要好好记住理解。

rehash操作
rehash解决了什么问题:通过扩容解决hash冲突,解决字典的性能问题。

扩容操作

哈希表的负载因子(used/size)
a. 如果没有进行bgsave 元素数量达到hash长度时就会扩容(负载因子大于等于 1)
b. 如果进行bgsave,元素数量达到hash长度的5倍会进行扩容(负载因子大于等于 5)
收缩操作

当哈希表的负载因子小于 0.1时, 程序自动开始对哈希表执行收缩操作。

负载因子是个动态值,满足一定条件的时候会触发rehash,rehash包括扩容和缩容

rehash步骤:

  1. 在字典中维持一个索引计数器变量 rehashidx , 并将它的值设置为 0 , 表示 rehash 工作正式开始;
  2. 为 ht[1] 分配空间, 让字典同时持有 ht[0] 和 ht[1] 两个哈希表

若是扩展操作,那么ht[1]的大小为>=ht[0].used*2的2^n
若是收缩操作,那么ht[1]的大小为>=ht[0].used的2^n

  1. 将保存在 ht[0] 中的所有键值对 rehash 到 ht[1] 上
  2. 当 ht[0] 包含的所有键值对全部迁移到了 ht[1] 之后,释放 ht[0] ,将 ht[1] 设置为 ht[0],并重置 ht[1] ,最好将 rehashidx 属性的值设为 -1 , 表示 rehash 操作已完成。

rehashidx还有一个作用:记录的是ht[0]的下标位置的位置,下次rehash就从该位置继续进行。

//部分代码
if (d->ht[0].used == 0) {
   
   // 释放ht[0]哈希表
    zfree(d->ht[0].table);
    // 将原来的ht[1]号哈希表设置为新的ht[0]哈希表
    d->ht[0] = d->ht[1
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值