Redis底层之字典

Redis底层之字典

字典,是一种用于保存键值对(key-value pair)的数据结构。

举个例子,我们向redis中写入:


msg就是键,“hello world”就是值,他们是一对键值对。

而许多这样的键值对组合在一起就成了哈希表。

Redis的字典就是使用哈希表作为底层实现,一个哈希表中存放多个哈希表节点(每个节点保存一个键值对)。

Redis字典使用的hash表结构如下:


table是一个数组,数组中的每一个元素都是指向一个dict.h/dictEntry结构,每个dict.h/dictEntry保存一个键值对。

size记录哈希表(即table数组)的大小,used属性记录哈希表目前已经有的节点的数量。sizemask的值总是等于size-1,这个值会和键的hash值一起决定这个键对应的键值对该存放在什么位置。



key保存键值对中的键,v保存这键值对中的值,键值对的值可以是一个指针,或者是一个uint64_t整数,或者是int64_t整数。


next属性指向另一个哈希表节点,这个指针将多个哈希值相同的键值对连接在一起,以此来解决键的冲突。


如下图就是将冲突的键值对用next指针相连:


Redis中的字典由dict.h/dict结构表示:


ht属性是一个包含两个项的数组,数组中的每个项都是一个dictht哈希表,一般只是用ht[0],只有在对ht[0]进行rehash时才会使用ht[1]。rehashidx等于-1时表示目前没有进行rehash。


随着操作的不断执行,哈希表保存的键值对会越来越多,如果冲突变多,导致链表变长,查询变慢,所以需要对哈希表进行扩容。有扩容就有收缩,当哈希表剩余空间太多时,就会缩小哈希表的空间。



扩容时会先为ht[1]申请足够的空间:


然后将ht[0]中的每一个键值对重新进行hash计算在ht[1]中找到对应的位置。


渐进式rehash

我们知道rehash是一个耗时比较长的过程(键值对数量可能非常大),如果在这个过程中有新的操作需要向哈希表中添加新的键值对,我们不会将它添加到ht[0],而是直接加到ht[1]。

下面看一下哈希表渐进式rehahs的步骤:


渐进式rehash的好处在于不需要将庞大的工作量在同一时间完成,避免了集中式rehash的庞大计算量。


在进行渐进式rehash执行期间的哈希表操作会在ht[0] ht[1]两个表中操作。

比如要查找一个键,会先在ht[0]中找,没有的话再到ht[1]中找。


总结:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值