当前位置: 首页 > wzjs >正文

pc网站直接转换成移动端的网站南昌地宝网租房信息网

pc网站直接转换成移动端的网站,南昌地宝网租房信息网,网页设计的最佳尺寸,莆田市住房和城乡建设信息网引言 作为Redis核心数据结构之一的哈希表(dict),其性能直接影响着Redis的整体表现。当数据量频繁增减时,哈希表需要动态调整容量以保持高效——这就是传说中的Rehash(重新哈希)。今天我们就来扒一扒Redis哈…

引言

作为Redis核心数据结构之一的哈希表(dict),其性能直接影响着Redis的整体表现。当数据量频繁增减时,哈希表需要动态调整容量以保持高效——这就是传说中的Rehash(重新哈希)。今天我们就来扒一扒Redis哈希表Rehash的底层逻辑,尤其是扩容/缩容时的渐进式迁移机制。


一、为什么需要Rehash?触发条件大揭秘

哈希表的核心矛盾是:空间利用率查询效率的平衡。当哈希表中元素太多或太少时,要么冲突激增(查询变慢),要么内存浪费(性价比低)。Redis通过**负载因子(Load Factor)**来量化这一矛盾,并以此触发Rehash。

负载因子怎么算?

负载因子 = 已存储键值对数量(size) / 哈希表桶的数量(table_size)。

触发Rehash的两种场景:

  1. 扩容触发(空间不够用):
    当负载因子 > 1 时(正常情况),或 Redis 正在执行 BGSAVE/BGREWRITEAOF 持久化时(负载因子 > 5)。
    原因:数据量超过桶数量,哈希冲突概率飙升(链式冲突链变长),查询时间复杂度可能从O(1)退化为O(n)。

  2. 缩容触发(内存浪费):
    当负载因子 < 0.1 时。
    原因:桶数量远大于实际数据量,大量空间被闲置,内存利用率低下。


二、Rehash的“双保险”:双哈希表设计

如果直接让原哈希表“暴力”扩容,所有数据需要重新计算哈希并插入新桶,这在数据量大时会导致Redis阻塞(主线程被长时间占用)。为了不影响线上服务,Redis设计了双哈希表结构:

typedef struct dict {dictType *type;          // 类型方法集合(哈希函数、比较函数等)void *privdata;          // 私有数据(如哈希种子)dictht ht[2];            // 核心:两个哈希表(ht[0]和ht[1])long rehashidx;          // Rehash进度(-1表示未进行)int16_t pauserehash;     // Rehash是否暂停(持久化时可能暂停)
} dict;
  • ht[0]:主哈希表,日常存储数据。
  • ht[1]:临时哈希表,仅在Rehash时使用,用于承接ht[0]迁移的数据。

Rehash的本质,就是把ht[0]的数据“搬家”到ht[1],完成后交换两者的角色(ht[0]指向原ht[1],ht[1]清空)。


三、渐进式Rehash:边干活边搬家,不阻塞服务

如果一次性迁移所有数据(比如ht[0]有100万键),主线程会被卡住很久,这对高并发场景是不可接受的。Redis的解决方案是渐进式Rehash——将迁移过程拆成无数个小步骤,每次操作(查询、插入、删除)时“顺手”迁移一点数据。

渐进式Rehash的具体流程:

1. 初始化阶段:启动Rehash

当触发Rehash条件时,Redis会:

  • 为ht[1]分配新内存(扩容时是ht[0].table_size×2,缩容时是ht[0].table_size/2,且必须是2的幂次方)。
  • 设置rehashidx=0(表示从ht[0]的第0号桶开始迁移)。
  • pauserehash设为0(允许其他操作参与迁移)。
2. 日常操作:捎带脚迁移数据

Rehash期间,每次对Redis执行增删改查操作时,都会触发一次“小迁移”:

  • 查询操作:先查ht[0]的当前桶(如果该桶已被迁移,就查ht[1]的同索引桶)。
  • 插入/更新操作:只往ht[1]写数据(避免修改正在迁移的ht[0])。
  • 删除操作:同时查ht[0]和ht[1],删除对应键(防止数据残留)。

每次操作后,rehashidx递增1,直到rehashidx等于ht[0].table_size(所有桶迁移完成)。

3. 收尾阶段:交换角色,释放旧表

当所有桶迁移完成后:

  • ht[0]和ht[1]交换身份(ht[0]指向原ht[1],ht[1]清空)。
  • 释放原ht[0]的内存(如果是缩容,可能保留小内存块复用)。
  • rehashidx重置为-1,Rehash结束。

四、关键细节:那些你可能忽略的设计巧思

1. 为什么桶的数量必须是2的幂次方?

哈希表的索引计算依赖哈希值与桶数量的取模运算。如果桶数是2的幂次方(如8、16、32),可以用位运算(hash & (table_size - 1))代替取模(hash % table_size),效率更高。扩容/缩容时,桶数翻倍或减半,索引计算依然高效。

2. 缩容也有底线:最小容量限制

为了防止频繁缩扩容,Redis规定缩容后的桶数至少为DICT_HT_INITIAL_SIZE(默认4)。即使负载因子低至0.05,也不会缩到比4更小。

3. 持久化期间的特殊策略

执行BGSAVEBGREWRITEAOF时,Redis会将扩容的负载因子阈值从1提高到5。这是因为持久化是磁盘IO密集型操作,此时如果触发扩容,可能导致主线程和持久化线程竞争CPU资源,影响性能。


总结:Rehash是Redis的“动态平衡术”

Redis的哈希表Rehash机制,通过双哈希表避免了数据迁移时的服务中断,通过渐进式迁移将大任务拆解为无数小步骤,确保了高并发场景下的稳定性。无论是扩容时的“空间换时间”,还是缩容时的“时间换空间”,本质上都是Redis对性能与内存利用率的精准权衡。

下次使用Redis时,不妨想想:当你执行SET key value时,可能正悄悄参与着一场“数据搬家”的大工程——这或许就是Redis“高性能”背后的浪漫吧! 😊

(注:文中涉及的源码解析基于Redis 7.0版本,不同版本可能有细微差异。)

http://www.dtcms.com/wzjs/587911.html

相关文章:

  • 手机做兼职的网站有哪些官方网站app最新下载
  • 网站开发能用react吗wordpress路由重写
  • 本地用织梦做网站wordpress页面内容设计
  • html个人网站公众号软文推广
  • 有关于做茗茶的网站中国建设信息化期刊
  • 低价网站建设浩森宇特百度推广开户联系方式
  • 南充楼盘网长沙网站搜索引擎优化
  • 做网站首页的要素外贸业务流程图
  • metro风格网站模板镇江网站设计公司报价
  • 网站做的好有什么用网站的建设方面如何写
  • 浙江网站建设推广公司十大排行wordpress动态菜单
  • 中企动力唐山网站建设做网站怎么去进行链接
  • 游戏网站建设赚钱wordpress文章占据边栏
  • 云南旅游网站学生个人网页设计模板
  • 辽宁天一建设有限责任公司网站互动网站策划
  • 免费的行情网站珠海网站备案
  • 小型深圳网站页面设计吴江做网站
  • 公司网站可直接购物支付源码分享平台
  • 开发网站能赚多少钱花都区网站建设
  • 加密网站wordpress 登录机制
  • 南宁网站设计创意互动网站
  • 公司网站建设介绍新版wordpress没有关键词
  • 宁都县建设局网站工商局外网
  • 中国移动网站建设百度推广一条资源多少钱
  • 樊城网站建设制作博客网站
  • 成都住建局官网报名入口网址资阳seo公司
  • 莱芜车管所网站龙岗网站建设公司怎么样
  • 山西大同网站建设价格主题网站建设平台
  • 网站开发费用摊销年限大学跳蚤市场网站建设
  • 怎样给网站做百度推广网络舆情的三种分类标准