redis基本数据类型——③哈希(字典)

hash(字典)(hset,hget,hlen,hmset 批量set,hincrby 自增)

  • Redis 的字典相当于 Java 中的 HashMap。
  • Redis 的字典与 HashMap 的相同点:无序,采用的数组 + 链表的结构,数组位置碰撞时,将碰撞的元素使用链表串接起来。
  • 不同点:Redis 字典的值只能是字符串,而 HashMap 的值可以是多种类型。另外它们 rehash 的方式不一样,因为 HashMap 在字典很大时,一次性全部 rehash 会是一个很耗时的操作,Redis 为了高性能,不能堵塞服务,所以采用了渐进式 rehash 的策略。渐进式 rehash 就是同时保留旧数组和新数组,在后续对 hash 的操作中渐渐的将旧数组中的数据迁移到新数组中,所以在操作处于 rehash 过程的字典时,需要同时访问新旧两个数组,如果在旧数组中找不到元素,就需要去新数组中查找。
  • redis 中每个字典都带有两个哈希表:ht[0] 和 ht[1],平时使用的是ht[0],ht[1] 只在进行 rehash 时使用。
  • redis的哈希表是如何解决冲突的?:它采用链地址法来解决键冲突的问题,每个哈希表节点都有一个next指针指向另一个哈希表,通过这个next指针将两个索引值相同的键连接起来。

字典rehash的步骤:(通过 rehash 操作来扩展或收缩哈希表)

  1. 为字典的 ht[1] 哈希表分配空间,这个空间大小取决于要执行的操作,以及 ht[0] 当前包含的键值对数量,也就是 ht[0].used 的值,used 记录哈希表已有的键值对数量,如果执行的是扩展操作,那么 ht[1] 的大小为第一个大于等于 ht[0].used x 2 的 2n ;如果执行的是收缩操作,那么 ht[1] 的大小为第一个大于等于 ht[0].used 的 2n
  2. 将保存在 ht[0] 中的所有键值对 rehash 到 ht[1] 上面,rehash 指的是重新计算键的哈希值和索引值,然后将键值对放到 ht[1] 哈希表中。
  3. 当 ht[0] 包含的所有键值对都迁移到 ht[1] 后,ht[0] 变为空表,释放 ht[0],将 ht[1] 设为 ht[0] ,并为 ht[1] 分配一个新的空白哈希表,为下一次 rehash 做准备。

渐进式rehash的原理(步骤)

  1. 为 ht[1] 分配空间,让字典同时持有 ht[0] 和 ht[1] 两个哈希表。
  2. 在字典中维持一个索引计数器 rehashidx,值设为0,表示开始 rehash 操作。
  3. 在 rehash 期间,每次对字典执行添加、删除、查找或更新操作时,程序会将 ht[0] 哈希表在索引上的键值对 rehash 到 ht[1] ,并将索引值加1。
  4. 随着字典操作的不断执行,最终 ht[0] 的所有键值对都会被 rehash 到 ht[1] ,然后将索引值设为 -1,表示 rehash 操作完成。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值