redis哈希表 rehash过程

  • redis哈希表结构 使用链地址方法来解决键冲突的,冲突后追加到链表后面。
  • redis中有两个哈希表,其中一个时正常使用的 ht[0],另一个是在扩容或者收缩时才需要的ht[1],一般为空
  • redis中的哈希表也是有 负载因子的
    负载因子 = 哈希表已保存节点数量 / 哈希表大小(桶的数量)
    load factor = ht[0].used / ht[0].size
  • redis扩容时机
    1.服务器未执行BGSAVE / BAREWRITEAOF 时,哈希表的负载因子 >= 1
    2 .服务器正在执行BGSAVE / BAREWRITEAOF 时,哈希表的负载因子 >= 5
    3 . 当负载因子小于 0.1时,执行收缩
  • redis扩容,收缩大小
    扩容:ht[1]大小为 >= ht[0].used * 2 的 2^n
    收缩:ht[1]大小为 >= ht[0].used 的 2^n
扩容步骤
  1. 先将保存在ht[0]中的所有键值对 rehash到ht[1]中:rehash就是重新计算key的hash值和索引值,然后将键值对放置到ht[1]哈希表的指定位置上
  2. 当ht[0]包含的所有键值对都迁移到了ht[1]后(ht[0]变为空表),释放ht[0],将ht[1]设置为ht[0],并将ht[1]新建一个空白哈希表,为下一次rehash做准备。
渐进式rehash

-如果哈希表中存在这几百万,几千万,几亿的数据时,那么一次性将这些键值对全部rehash到ht[1]的话,会导致一段事件内redis服务器停止对外服务

步骤:

  1. 为ht[1]分配空间,让字典同时拥有两个哈希表
  2. 在字典中维持一个rehashidx变量设为0,表示rehash正式开始
  3. 在rehash期间,每次对字典进行添加,删除,查找或者更新操作时,程序除了执行指定的操作外,还会顺带将将ht[0]哈希表在rehashidx索引上的所有键值对rehash到ht[1]当rehash工作完成后,程序将rehashidx属性+1
  4. 随着字典操作不断执行,最终在某个时间点上,ht[0]的所有键值对都会rehash至ht[1],这时程序会将rehash属性的值设为-1,表示rehash操作已完成

好处:

渐进式rehash的好处在于他采取分而治之的方式,将rehash键值对所需要的计算工作均摊到对字典的每个添加、删除、查找和更新操作上,从而避免集中式rehash而带来的庞大的计算量。

rehash期间的操作:

  1. 渐进式rehash期间,字典的删除、查找、更新等操作会在两个哈希表上进行。例如:要在字典里面找一个key,程序会先在ht[0]里进行查找,如果没找到,就会继续到ht[1]中进行查找
  2. 渐进式rehash期间,新添加到字典的键值对一律会保存到ht[1]里,ht[0]则不会进行任何添加操作,这保证了ht[0]包含的键值对数量只减不增,并伴随这rehash操作的执行,最终变成空表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值