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 ...
随机推荐
- What you should know about .so files
In its early days, the Android OS was pretty much supporting only one CPU architecture: ARMv5.Do you ...
- 中国标准时间、‘yyyy-MM-dd’格式时间转为时间戳
中国标准时间转为时间戳 let _time="Tue Mar 20 2018 00:00:00 GMT+0800 (中国标准时间)"; console.log(Date.parse ...
- win10 与linux mint双系统 只能进入mint而无法进入windows的解决方案
新购买了一块ssd,和以前的hdd硬盘一起装双系统:win10和mint ssd:win10 sdb1 sdb2 sdb3 sda2 hdd: mint sda1 ...
- JavaScript 闭包(Closure)
闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包-无处不在 在前端编程中,使 ...
- all hands meeting
今天某导师联系我说:"There will be an allhand" 搞不懂allhand是啥意思……他口头跟我解释的是就是个茶话会性质的小会~ 我在网上查了一下,这个用法很少 ...
- iOS - WKWebView的使用和长按手势识别二维码并保存
WKWebView的图片二维码使用: .长按手势识别二维码并保存 .识别二维码跳转;不是链接显示内容点击网址跳转 .解决url包含中文不能编码的问题 .文字带链接网址,点击跳转 .纯文本-文字html ...
- R排序sort、order、rank、arrange
Ø sort sort(x, decreasing = FALSE, ...) ## Default S3 method: sort(x, decreasing = FALSE, na.last = ...
- confirm
注意confirm是window对象的方法,当确认时,返回true,取消时,返回false
- poj1850Code
Code Transmitting and memorizing information is a task that requires different coding systems for th ...
- python字典获取最大值的键的值
有时我们需要字典中数值最大的那个键的名字,使用max(dict, key=dict.get)函数非常的方便 key_name = max(my_dict, key=my_dict.get) 获取之后你 ...