Redis学习08--字典的rehash过程

本文详细介绍了Redis字典的rehash过程,包括rehash的目的、触发条件和渐进式rehash。当负载因子超过一定阈值时,Redis会进行哈希表的扩展或收缩。rehash操作会分步将ht[0]的键值对转移到ht[1],以确保系统资源的合理使用。渐进式rehash旨在避免一次性rehash大量数据导致的服务中断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【说明:本系列文章所有思维导图均为纯手工打造,转载请注明出处】 

关于部分热心朋友提醒的几点说明

1)有朋友反映说为啥我的博客很多都是只放一张图,对读者很不友好。这里说明下原因:

  • 本人很懒加上时间有限,为了保持博客编写速度尽可能高效, 觉得思维导图在逻辑结构上更直观,图能表达的内容,不愿意再用文字赘述一遍;
  • 本人习惯用思维导图的形式串联知识点,觉得通过文档目录来串联知识点并体现层级结构的方式比较麻烦;
  • 本人博客所有内容均为自主学习过程中形成的思维导图笔记。

2)有朋友反映说思维导图无法很好的承载表现一些复杂的内容:

  • 这个确实,哈哈,无法反驳;
  • 本人由于水平有限,思维导图大部分内容可看作各相关知识点的一个概述,所有通过思维导图没有讲到、或者讲解的不够清楚有纰漏、或者不够深入的地方可通过别的途径进行补充学习,更伟大的做法是“评论区留言,大家一起探讨学习”

1.关键数据结构及元素 

  • Redis字典的结构

        dictType *type;  //类型特定函数
        void *privdata;  //私有数据
        dictht ht[2];       //哈希表
        in trehashidx;    //rehash索引,没有进行Rehash值为-1

  • dictht的结构:

{
    dictEntry **table; //哈希表数组
    unsigned long size;  //哈希表大小
    unsigned long sizemark;//大小掩码
    unsigned long used; //已使用节点数量
};

  • dictEntry结构:

{
    void* key;
    struct dictEntry *next;
    union{
        void *val;   unit64_tu64;   int64_ts64;
    } v;
};

  •     字典负载因子:ht[0].used/ht[0].size

2.rehash概述

2.1 目的
        随着哈希表保存键值对的主键增多或减少,为了使哈希表的负载因子维持在一个合理范围,当哈希表保存的键值太多或者太少时,程序会对哈希表的大小进行响应的扩展或者收缩。

2.2.触发条件

2.2.1扩张触发条件

  • 服务器没有执行BGSAVE或者BGREWRITEOF命令,并且负载因子大于1;
  • 服务器在执行BGSAVE 或者BGREWRITEOF命令,并且负载因子大于等于5

        为什么在执行BGSAVE时,会提升负载因子的阈值?
        为了避免在执行BGSAVE时执行扩张,最大限度的节约内存。
2.2.2收缩触发条件
            负载因子小于0.1时
2.3rehash流程
        1)为字典的ht[1]哈希表分配空间,空间大小取决于要执行的操作和ht[0]当前包含的键值对数量

                如果是扩展操作,ht[1]的大小为第一个大于等于ht[0].used*2的2的n次方幂。例如ht[0].used=10,那么大于ht[0].used*2=20的第一个2的n次方幂是32。

                如果是收缩操作,ht[1]的大小为第一个大于等于ht[0].used的2的n次方幂。例如ht[0].used=10,那么大于ht[0].used的第一个2的n次方幂是16。

        2)将保存在ht[0]中的所有键值rehash到ht[1]上(采用的时渐进式hash)
        3)当ht[0]所有的键值都迁移到ht[1]后,释放ht[0],并将ht[1]设置为ht[0],并在ht[1]新建一个空白的哈希表,为下次rehash做准备。
2.4渐进式hash
2.4.1为什么需要渐进式hash

        为了防止当字典中数据量过大,执行rehash会严重消耗系统资源,甚至导致服务器停止服务。
2.4.2运行流程
        1)为ht[1]分配空间,具体参见上面rehash步骤1的说明
        2)同时将字典结构中的索引计数器rehashidx字典值置为0,表示rehash工作正式开始;
        3)每次对字典执行增删改查时,会将ht[0]哈希表在rehashidx索引上的所有键值对reshah到ht[1](也就是每次rehash一个桶的数据),当rehash完成后,rehashidx值加1(使下次rehash时操作的是下一个桶的数据)。
        4)当某个时间点,ht[0]所有的键值对都被rehash到ht[1]时,将rehashidx的值置为-1,表示rehash完成。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值