博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis学习笔记——dict
阅读量:7236 次
发布时间:2019-06-29

本文共 1710 字,大约阅读时间需要 5 分钟。

Redis里字典(dict)主要用在两个场景:

1、保存数据库的键值对
2、Hash类型的底层实现之一(另一种是通过压缩列表实现)

数据结构定义

字典的定义如下:

/* * 字典 * * 每个字典使用两个哈希表,用于实现渐进式 rehash */typedef struct dict {    // 特定于类型的处理函数    dictType *type;    // 类型处理函数的私有数据    void *privdata;    // 哈希表(2 个)    dictht ht[2];    // 记录 rehash 进度的标志,值为 -1 表示 rehash 未进行    int rehashidx;    // 当前正在运作的安全迭代器数量    int iterators;} dict;

(以上注释来自《Redis设计与实现》)

哈希表dictht的定义如下:

/* * 哈希表 */typedef struct dictht {    // 哈希表节点指针数组(俗称桶,bucket)    dictEntry **table;    // 指针数组的大小    unsigned long size;    // 指针数组的长度掩码,用于计算索引值    unsigned long sizemask;    // 哈希表现有的节点数量    unsigned long used;} dictht;

哈希表用链地址法来解决碰撞。这里table是个二级指针,每个指针指向了对应索引的节点连成的链表。

哈希表节点定义如下:

/* * 哈希表节点 */typedef struct dictEntry {    // 键    void *key;    // 值    union {        void *val;        uint64_t u64;        int64_t s64;    } v;    // 链往后继节点    struct dictEntry *next;} dictEntry;

哈希表性能问题

哈希表的性能取决于大小(dictht的size属性)与保存节点数量(dictht的used属性)之间的比率:

1、哈希表的大小与节点数量,比率在 1:1 时,哈希表的性能最好;
2、如果节点数量比哈希表的大小要大很多的话,那么哈希表就会退化成多个链表,哈希表本身的性能优势便不复存在。

rehash解决性能问题

之所以前面定义dict的时候,用了两个哈希表dictht,是因为,在哈希表的节点比较多的时候,在第一个哈希表ht[0]上查找比较慢,这时,就需要对哈希表重新调整,也就是rehash。

关于rehash,有以下几点需要注意:
1、创建一个更大的哈希表,然后赋给ht[1],将ht[0]上的节点移动到ht[1]上,移动结束后,将ht[1]设置为ht[0]。
2、rehash分主动和被动,主动是指,Redis的常规服务定时去检查并且rehash,被动是指,用户在添加新键值对时触发rehash。
3、当哈希表比较大的时候(表大,节点多),进行rehash可能会比较慢,这个时候,rehash不是一步阻塞完成的,是“渐进式”的,也就是分几次完成,也就是,我这次移动1个索引的全部节点,下次常规服务里移动另一个索引的节点,以这种方式来完成rehash。
4、在rehash的过程中,会同时使用到两个哈希表,新添加进来的节点是放在ht[1]上。个人猜测是因为,ht[1]是rehash的最终结果,如果添加在ht[0]上,还需要多做一步,把ht[0]上的移动到ht[1]上。
5、在查找删除的时候,会同时操作ht[0]和ht[1],因为在rehash的过程中,哈希表分布在这两个表上。

收缩字典防止浪费资源

当比值 used*100/size 小于10的时候,也就是字典的填充率小于10%的时候,就收缩字典,收缩过程与rehash过程类似,不过ht[1]比ht[0]小。收缩是由常规服务检查触发的,用户不会触发收缩。

参考:

1、《Redis设计与实现》

转载地址:http://aagfm.baihongyu.com/

你可能感兴趣的文章
面试中,应聘者问面试官的问题
查看>>
用js实现翻牌的效果
查看>>
Linux 中文设置
查看>>
再写mock对象
查看>>
hg vs git :这个世界除了svn还有别的
查看>>
BZOJ1095:[ZJOI2007]Hide 捉迷藏(动态点分治)
查看>>
[LeetCode] Word Break II
查看>>
两句话解决代理问题
查看>>
熊市中,值得关注的项目都有这三大特征
查看>>
2018.12.27-dtoj-4089-line
查看>>
10:比较整数大小经典案例
查看>>
ES06--elasticsearch
查看>>
pytorch1.0 用torch script导出模型
查看>>
数据结构(九)查找
查看>>
JAVA常用的集合类
查看>>
Unity3D MainCamera和NGUI UICamera的小插曲
查看>>
gnuWin32-mini-2016.10.30
查看>>
Cassandra博客更新预告
查看>>
Linux 格式化和挂载数据盘
查看>>
mybatis 中 prefix="" suffixOverrides="," prefixOverrides="" suffix=""
查看>>