redis学习系列(五)--redis基础字典的构造
来源:互联网 发布:java软件公司 编辑:程序博客网 时间:2024/06/06 07:41
最近真是有点疯啊,更新的有点勤快,主要还是最近项目处于一个真空期,迭代版本已经准备好,等着上线,下个版本需求已经完成大半,并且没什么复杂的,因此读书时间比较多,项目中其实用过redis,并且redis是集群的,用来保存分布式session和用作缓存使用的,配置文件我不知道,但是等这边的一些知识看完回去研究一下公司内部的redis代码,都是大神写的,看看还是不错的。
这一篇来看看字典的内部构造,其实看这些东西,感觉很枯燥,但是又必须要过一遍,不然你不知道用起来的时候它里面什么样子,只知道使用可不是个好现象。
字典的底层实现就是 : 字典-->哈希表-->哈希节点-->键值对
哈希表
table是一个数组,数组中每一个元素都是执行一个entry的指针,每一个entry都保存着一个键值对。size保存了哈希表的大小,就是table数组的大小
used记录了哈希表目前已有节点的数量
sizemask属性的值总是等于size-1,这个属性和哈希值一起决定一个键应该被放到table数组的哪个索引上面
一个空的哈希表
哈希表节点
哈表表内的节点用entry表示,每个entry保存着一个键值对
key保存着键值对中的键,而v属性保存着值,其内部保存的数据暂时不去追究,可以是指针,可以是uint64_t整数,可以是int64_t整数next属性执行另一个哈希表节点的指针,注意这个指针可以将多个entry链接起来形成链表,其实就hashmap一样,是解决hash冲突的。
字典
回到最外层的构造,
type和privdata是针对不同类型的键值对而设置的,了解一下:type是执行dictType结构的指针,每个type指针保存了一簇用于操作特定类型键值对的函数
privdata则是保存了需要传给那些特定函数的可选参数。
ht属性则是我们上面说过的哈希表存放的地方,内部有两个数组组成,一般情况下字典只使用ht[0]哈希表,而ht[1]则是对ht[0]进行rehash时使用。而要进行rehash,另一个值就是rehashidx。
图为普通状态下的字典:
hash算法
与hashmap类似,redis里面使用的hash算法也是需要先计算hash值,然后再计算索引值,最后再将元素放到指定位置上去。
数据被存放进字典
hash冲突
使用链表法解决冲突。同理,最新插入的也是在最前面。
rehash
redis会对哈希表进行扩展或者收缩,以维持负载因子在一个合理的范围之内
执行步骤分成3个阶段:
1.为字典ht[1]哈希表分配空间,这个空间大小取决于执行的操作,以及当前ht[0]的所保存的键值对数量,也就是ht[0].used的值
1.1 如果是扩展操作,那么ht[1]的大小为第一个大于等于ht[0].used * 2的 2^n的值
1.2 如果执行收缩操作,那么ht[1]的大小为第一个大于等于ht[0].used的2^n的值
2.将保存在ht[0]中的所有键值对rehash到ht[1]上面
3.当ht[0]包含的所有键值对都迁移到ht[1]上面后,释放ht[0],将ht[1]设置成ht[0],并在ht[1]处新建空白哈希表
原始字典值:
分配空间
移动到ht[1]处
清除ht[0],并更名及重新生成空白ht[1]。
hash表的扩展与收缩
满足以下条件之一,程序会自动开始对哈希表进行扩展操作
1.服务器没有执行BGSAVE或者BGREWRITEAOF命令,并且hash表的负载因子大于等于1。
2服务器正在执行BGSAVE或者BGREWRITEAOF命令,并且hash表的负载因子大于等于5.
负载因子 = ht[0].used / ht[0].size
说明: 因为在BGSAVE或者BGREWRITEAOF期间,redis需要创建当前服务器进程的子进程,因此在子进程期间会扩大执行进展所需要的负载因子,尽可能避免在子进程存在期间进行哈希表扩展操作,节约内存。
当负载因子小于0.1时,会自动进行收缩操作。
- redis学习系列(五)--redis基础字典的构造
- redis学习系列(四)--redis基础SDS的构造
- redis学习系列(六)--redis基础跳跃表的构造
- redis学习系列(八)--redis-RDB基础
- redis学习系列(八)--redis-AOF基础
- Redis学习笔记(五)Linux下redis的安装
- Redis学习(五)Redis的持久化
- redis系列(一)redis基础
- redis的基础学习
- noSQL-redis学习(五) -- redis事务
- Redis学习五(Spring Data Redis)
- redis学习系列(七)--redis-database
- Redis 学习 ---- 4.字典
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
- Redis 讲解系列之 Redis的五大数据类型
- Redis笔记(五)Redis的事务
- STM32F103的普通定时器中断问题,存在开机后初始化,一打开允许中断,定时器立刻进入中断函数一次
- JavaScript 中的数据类型
- jmeter http请求 正则表达式提取器 java请求 高手教程
- System.Timers.Timer定时器的使用
- 单点登录方式整理笔记
- redis学习系列(五)--redis基础字典的构造
- 页面数据以弹出框的形式提交到另一个action中
- LeetCode 14.Longest Common Prefix
- mongodb切片的使用与维护
- Http请求和HttpServletRequest中获得对应参数的方
- gamma
- 【Python】2.1温度转换
- Read-only file system
- Spring中的@Transactional放在 类级别 和 方法级别 上有什么不同?