Redis渐进式rehash过程图

概念

扩展或收缩哈希表需要将 ht[0] 里面的所有键值对 rehash 到 ht[1] 里面, 但是, 这个 rehash 动作并不是一次性、集中式地完成的, 而是分多次、渐进式地完成的。

那么为什么要这么做呢,如果这时候我的哈希表里的节点数据很多大到几十万百万的话,将这些键值对全部 rehash 到 ht[1] 的话, 庞大的计算量可能会导致服务器在一段时间内停止服务。

 

rehash整体过程:

1、字典的数据结构里有ht这个哈希表的引用,就是 ht[0] 和 ht[1] 两个哈希表。

2、字典的数据结构里dictht里有个rehashidx字段是维护我们rehash的进度的,默认是-1,设置成0就标识开始rehash了,在后面每一次rehash就会+1,直到rehash完成在设置成-1

3、rehash的过程中会对used和dictEntry操作扩容或者缩容,首先会分配一个ht[1]空间,根据2的n次方幂等方式,比如一开始我used=4,那么4*2=8下一个dictEntry容量就是8扩容,每一次渐进的时候都会把原来ht[0]的dictEntry节点指向NULL,在赋值给ht[1],最终在把完成ht[1]后的替换为ht[0],在把ht[1]创建一个空哈希表,这样整个rehash就算完成。

下面是rehash的完成过程

 

1、准备rehash

 

这时候是刚要进行rehash,还未开始的时候rehashidx=-1,dictEntry=4

2、开始reahsh第一步

这时候开始rehash,rehashidx=0,把ht[0]的dictEntry节点k1的设置为null,ht[1]的dictEntry扩容为=8的并且把k1的赋值给ht[1]的dictEntry

3、最后rehash完成前

这时候基本上已经把ht[0]的dictEntry都赋值给了ht[0]了,基本已经完成

4、最后完成rehash

 

 

rehash过程请求数据怎么处理的

因为在进行渐进式 rehash 的过程中,会存在 ht[0] 和 ht[1] 两个哈希表, 所以期间所有操作两个哈希表上进行,会先在 ht[0] 里面进行查找再就会继续到 ht[1] 里面进行查找。

另外, 在新增键值对保存到 ht[1]而不会新增到 ht[0], 这就是符合后面的rehash的过程了,不然你又保存到了ht[0]了就会产生数据不一致了

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值