Redis的设计与实现——字典
绝大多数语言中的字典底层实现基本上都是哈希表。哈希表中用 “负载因子” 来衡量哈希表的 空/满 程度。为了让负载因子在一定的合理范围之内,提高查询的性能,一般的做法是让哈希表扩容,然后rehash一把。
but,扩容也不一定就能解决负载因子过大的问题。Redis作为一款成熟的非关系型数据库,肯定有他的独到解决办法!!!能够保证rehash是有效的。
讲解rehash之前看下redis里面的一些数据结构:字典的底层有哈希表实现,ht存放的是哈希表。

Redis对字典的rehash的步骤如下:
①为字典的ht[1]分配空间,空间的大小取决于要执行的操作(扩展还是收缩)以及ht[0]的used属性。
扩展:ht[1]的大小为 第一个大于等于 ht[0].used*2 的 2n。
收缩:ht[1]的大小为 第一个大于等于 ht[0].used 的 2n。
②将ht[0]里面的键值对rehash到ht[1]。
③都迁移到ht[1]之后,释放ht[0],将ht[1]设置为ht[0],然后在ht[1]新建空白哈希表。为下一次rehash做准备。
写道这里,我还是没有搞清楚这个redis的哈希设计高效在哪里?直到我看到了渐进式hash!!!
渐进式hash
何为渐进式hash?在上面提到的rehash中,不是一次性将ht[0]的数据送入ht[1],如果数据量过大,将会严重影响redis数据库的性能,所以采用了一种方法渐进式。
渐进式具体操作呢?
①给ht[1]分配空间,让字典同时持有两个哈希表ht[0]和ht[1]。
②利用一个巧妙地数据设计,rehashidx,初值设为-1,表示不需要rehash;一旦需要rehash的时候,设置为0,表示rehash工作正式开始。
③在rehash进行期间,除了执行指定的操作(增删改查)之外,还会附加做一些工作,就是将ht[0]上的rehashidx对应的所有键值对rehash到ht[1]上,移完之后,rehashidx加1.
④随着字典操作(增删改查)的不断执行,最终会在某个时间点上,ht[0]的所有键值对都会被rehash到ht[1]上,这时程序将rehashidx设置为-1,表示rehash操作已全部完成。rehash的过程中,添加操作只会在ht[1]上进行,这样能够保证ht[0]的键值对只减不增。
渐进式rehash操作的好处是,避免了集中式rehash操作,将rehash的操作分摊到每次的数据库操作上。

Redis的设计与实现——字典的更多相关文章
- [Redis]Redis的设计与实现-链表/字典/跳跃表
redis的设计与实现:1.假如有一个用户关系模块,要实现一个共同关注功能,计算出两个用户关注了哪些相同的用户,本质上是计算两个用户关注集合的交集,如果使用关系数据库,需要对两个数据表执行join操作 ...
- Redis --> Redis架构设计
Redis架构设计 一.前言 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列 ...
- redis 系列5 数据结构之字典(上)
一. 概述 字典又称符号表(symbol table),关联数组(associative array), 映射(map),是一种用于保存键值对(key-value pair)的抽象数据结构.在字典中, ...
- 11.Redis缓存设计
11.Redis缓存设计11.1 缓存的收益和成本11.2 缓存更新策略11.3 缓存粒度控制11.4 穿透优化11.5 无底洞优化11.6 雪崩优化11.7 热点key重建优化11.8 本章重点回顾
- Redis缓存设计及常见问题
Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使 用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的 ...
- Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理
基于python+mysql浅谈redis缓存设计与数据库关联数据处理 by:授客 QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3 ...
- 【Redis源代码剖析】 - Redis内置数据结构之字典dict
原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/article/details/51018337 今天我们来讲讲Redis中的哈希表. 哈希表在C++中相应的是ma ...
- redis数据库设计(转)
原文:http://segmentfault.com/q/1010000000316112 redis是什么 redis就是一个存储key-value键值对的仓库,如何使用redis在于如何理解你需要 ...
- 17 redis -key设计原则
书签系统 create table book ( bookid int, title char(20) )engine myisam charset utf8; insert into book va ...
随机推荐
- pam和sasl
这几天使用在Postfix搭建一个Webmail的平台,用户认证这一块最终使用了PAM.想整理一下思路,让自己对PAM有个更加清晰的认识. 1. PAM的简介 PAM全称是:Pluggabl ...
- mongodb gridfs基本使用
Mongodb GridFS图片文件存储解决方案 之前解决方案是接收图片数据后,将图片直接存储到盘阵,然后通过Apache做服务器,将图片信息存储到数据库,并且存储一个Apache的访问路径. 目前需 ...
- C语言qsort用法
一.对int类型数组排序 int num[100]; Sample: int cmp ( const void *a , const void *b ) { return *(int *)a - *( ...
- elasticsearch的索引自动清理及自定义清理
近发现elasticsearch近期索引文件大的吓人,清理了下之前的索引文件,发现服务器性能大大的减轻了一半,想一直保留近一个月的索引文件,但是又不想每个月手动清楚,在此写了一个小脚本 查询索引: c ...
- Css 中的 block,inline和inline-block概念和区别
1.block和inline这两个概念是简略的说法,完整确切的说应该是 block-level elements (块级元素) 和 inline elements (内联元素).block元素通常被现 ...
- 推荐系统之余弦相似度的Spark实现
推荐系统之余弦相似度的Spark实现 (1)原理分析 余弦相似度度量是相似度度量中最常用的度量关系,从程序分析中, 第一步是数据的输入, 其次是使用相似性度量公式 最后是对不同用户的递归计算. ...
- HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]
题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...
- JavaScript学习12.1
JavaScript弹窗可以创建3种消息框:警告框.确认框.提示框,可以不带window对象直接使用相应的方法警告框:保护用户可以得到某些信息,当出现警告框后需要用户点击确认按钮之后才能操作windo ...
- CCCC L2-022. 重排链表
题解:直接list模拟,头尾两个指针,分别将头尾元素push到另一个list里面,输处输入方式同上一篇 坑:第一发卡了第二个样例,第二发卡了第4个,莫名其妙,所以把两个代码合起来,然后强行ac了. # ...
- hue安装及基本测试-笔记
#################################################################################################### ...