【redis源码之hash】

本文详细探讨了Redis中的字典数据结构,包括hashtable实现、rehash过程及其条件,以及扩容和缩容策略。重点介绍了如何理解并操作Redis的内置字典,以及为何采用渐进式rehash技术以保持高效性能。

深入redis hash (字典)内部

数据结构

字典是redis中出现最为频繁的一种数据结构,除了hash类型外,redis中所有的key-value 组成一个全局字典,带有过期时间的key和其过期时间也是一个字典。zset集合中存储的value和score也是一个字典。

struct RedisDB{
	dict *dict;//all keys =>value
	dict *expires: //all expired key=> time
}
struct zset{
	dict *dict;//all value=>score
	zskiplist *zsl;
}

redis中的字典结构实际上是有两个hashtable(h(0),h(1)),一般情况下只有一个hashtable是有值的。hashtable的数据结构和java的hashmap是一样的,通过分桶的方式解决hash冲突。当rehash时,会将值迁移到另外一个备用的hashtable中。
java中的rehash是一步到位的,是O(n)级别的操作,redis是单线程的,不允许这样耗时的任务进行,而是通过渐进式rehash的方式进行。

渐进式rehash

1 为 ht[1] 分配空间, 让字典同时持有 ht[0] 和 ht[1] 两个哈希表。
2 在字典中维持一个索引计数器变量 rehashidx , 并将它的值设置为 0 , 表示 rehash 工作正式开始。
3 在 rehash 进行期间, 每次对字典执行添加、删除、查找或者更新操作时, 程序除了执行指定的操作以外, 还会顺带将 ht[0] 哈希表在 rehashidx 索引上的所有键值对 rehash 到 ht[1] , 当 rehash 工作完成之后, 程序将 rehashidx 属性的值增一。
4 随着字典操作的不断执行, 最终在某个时间点上, ht[0] 的所有键值对都会被 rehash 至 ht[1] , 这时程序将 rehashidx 属性的值设为 -1 , 表示 rehash 操作已完成。
    
注意:rehash 阶段 操作都是在两个hashtable上进行的,但是添加操作只会在h(1)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扩容、缩容条件

当元素个数等于数组的长度是即开始扩容,扩容大小是增加一倍的容量。如果此时正在bigsave,为了减少内存页的过多分离COW,redis会选择不扩容。但是,当元素个数增加到数组的5倍时,就会强行扩容。
当元素个数小于数组长度的10%,就会触发缩容,缩容是不会考虑bigsave。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值