【redis前传】redis字典快速映射+hash釜底抽薪

前言

本篇仍然定位在【redis前传】系列中,因为本篇仍然是在解析redis数据结构!

应用场景

  • 而今天我们的主角就是五种数据结构的Hash分析。

image-20210624164553947

  • 上面这张图诠释了作为redis底层结构的Hash。
  • 在hictht类中有四个属性分别是table 、 size 、 sizemask 、 used 
  • dictEntry就是真正存储数据的。
  • 至于为什么sizemask = size -1 ; 这个是为了在计算hash索引时需要用到的。

数组节点

  • 上面的哈希表是不是很熟悉,这不和Java中的Map数据结构如出一辙吗。
  • 在上面中我们提到数据最终是存储在哈希表里table数组里的元素。该元素叫dictEntry 。 

image-20210624165611646

  • 通过左侧对dictEntry的定义我们可以看出。dictEntry存储的值可以是指针、正数、浮点数各种数据类型
  • 既然是数组那么索引就是固定长度的,那么在有限的长度中肯定会出现经典问题就是【hash冲突】。
  • 这里我们就可以和Java中的Map结构进行理解。他们内部很是相似!!!

image-20210625113012772

字典

多态字典

  • 字典是本文开头提出的结构!也是redis中大量使用的一种底层数据结构。在redis中名叫做dict类。

image-20210625110556458

  • 通过图示我们明确的看出内部是包含哈希表的。
  • 之前也提到过redis内部很多地方会使用到字典!就好比我们上学是用到【新华字典】、【成语词典】、【歇后语词典】等等。虽然名字叫法不一样但是内部结构都是一部字典供我们快速定位。而redis中dict内部就是通过type字段进行区分每个字典的。而privdata是每部字典需要的特定参数。通过type和privdata就可以轻松实现各种功能不同的字典,他有个专有名词叫~~多态字典~~

rehash

  • 除了type 、 privdata以外剩下的就是ht 、 rehashidx了。其中ht是一个长度为2的数组。数组里元素就是我们之前提到了哈希表(dictht) 。
  • 在实际使用过程中在字典中我们所有的数据都会存储在ht[0]对应的哈希表中。ht[1]永远都是一个空数组。
  • 首先我们在哈希表中是一个定长数组发生冲突时内部是通过链表解决的。理论上一个哈希表可以存储足够的数据,这里的足够就是指空间允许的范围有多少存多少。
  • 每次数组发生长度变化时,那么之前的hash值就需要重新经历一遍hash然后寻址index的过程。这个过程就叫做rehash

image-20210625133555602

  • 关于rehash和Java中Map的resize是一样的功能!
  • 那么啥时候需要进行rehash呢?这里和Java的负载因子一样;

image-20210625140300363

  • 涉及到上述两个命令的我们称之为后台命令结合负载因子产生如下条件

image-20210625140528097

image-20210625142224557

image-20210625142326375

渐进式rehash

  • 一直强调redis是单线程。那么什么叫单线程模型?就是对于redis服务来说执行命令是线性操作!但是每个客户端的命令是无序的,先到的就先进入队列redis服务从队列一次取出命令进行执行。

  • ①、首先为了避免阻塞客户端或者说尽量控制阻塞的时间在客户端感知范围内,redis内部的rehash并不是一次性操作而是一个循序渐进的过程。一次仅复制一部分

  • ②、还记得之前我们提到dict中rehashidx这个属性吗,他是记录rehash的进度。因为哈希表内部是一个数组而rehashidx就是记录这个数组的索引。从而我们也可以知道每次rehash复制的时候是已一个索引完整链表为单元进行复制的。

  • ③、除了新增以外的其他操作都会同时影响到ht[0]、ht[1] 因为在rehash过程中两个数组都是在使用状态的

  • ④、新增值的时候就只需要新增到ht[1]中。

  • ⑤、在rehash过程中查找元素时会查找两个数组中的并集元素。

总结

①、字典表在redis被广泛使用,基于字典表优秀的设计解决redis单线程问题

②、字典里包含哈希表,哈希表内部使用节点负责存储key、value

③、字典type实现多态字典用于多场景!

④、渐进式rehash解决服务卡顿问题

点赞、关注不迷路哦

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值