参考博客

绝大多数语言中的字典底层实现基本上都是哈希表。哈希表中用 “负载因子” 来衡量哈希表的 空/满 程度。为了让负载因子在一定的合理范围之内,提高查询的性能,一般的做法是让哈希表扩容,然后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的设计与实现——字典的更多相关文章

  1. [Redis]Redis的设计与实现-链表/字典/跳跃表

    redis的设计与实现:1.假如有一个用户关系模块,要实现一个共同关注功能,计算出两个用户关注了哪些相同的用户,本质上是计算两个用户关注集合的交集,如果使用关系数据库,需要对两个数据表执行join操作 ...

  2. Redis --> Redis架构设计

    Redis架构设计 一.前言   Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列 ...

  3. redis 系列5 数据结构之字典(上)

    一. 概述 字典又称符号表(symbol table),关联数组(associative array), 映射(map),是一种用于保存键值对(key-value pair)的抽象数据结构.在字典中, ...

  4. 11.Redis缓存设计

    11.Redis缓存设计11.1 缓存的收益和成本11.2 缓存更新策略11.3 缓存粒度控制11.4 穿透优化11.5 无底洞优化11.6 雪崩优化11.7 热点key重建优化11.8 本章重点回顾

  5. Redis缓存设计及常见问题

    Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使 用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的 ...

  6. Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理

    基于python+mysql浅谈redis缓存设计与数据库关联数据处理 by:授客  QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3 ...

  7. 【Redis源代码剖析】 - Redis内置数据结构之字典dict

    原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/article/details/51018337 今天我们来讲讲Redis中的哈希表. 哈希表在C++中相应的是ma ...

  8. redis数据库设计(转)

    原文:http://segmentfault.com/q/1010000000316112 redis是什么 redis就是一个存储key-value键值对的仓库,如何使用redis在于如何理解你需要 ...

  9. 17 redis -key设计原则

    书签系统 create table book ( bookid int, title char(20) )engine myisam charset utf8; insert into book va ...

随机推荐

  1. 题目1013:开门人和关门人(结构体自定义cmp排序)

    题目链接:http://ac.jobdu.com/problem.php?pid=1013 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...

  2. nginx fastcgi配置

    1.1 nginx概述nginx简介Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/P ...

  3. Word插入htm文件导致文本域动态增加的一个问题

    受html标签影响,超链接也会被变成文本域(HYPERLINK).当遍历文本域进行替换之前如果预存了文本域的数量(Count/Length/etc.)将导致遗漏.

  4. matlab的m程序转执行文件exe

    转换主要有两步: 第一步 设置编译器 在命令窗口输入 mbuild -setup 根据提示操作即可,.如下图我的设置 第二步 转换执行文件 命令行输入 mcc -m main   即可(输入 mcc ...

  5. iOS8跳转到系统设置页

    版权声明:本文为博主原创文章,未经博主允许不得转载. 大家都知道,在iOS5.0时时可以跳转到系统的设置页的.但是在5.1之后就不可以了. 刚才研究了下这个问题,发现只有iOS8可以跳转到系统设置里自 ...

  6. iOS - 去除数组中重复数据的几种方法

    第一种:利用NSDictionary的AllKeys(AllValues)方法 代码: NSArray *dataArray = @[@"2018-02-01",@"20 ...

  7. iOS - 获取音视频文件的Metadata信息

    // // MusicInfoArray.h // LocationMusic // // Created by Wengrp on 2017/6/22. // Copyright © 2017年 W ...

  8. python基础-动态加载lazy_import(利用__import__)

    看了一天动态加载,普遍有这么几种方法,总结一下,由简入深,本文仅对查到的栗子们做个引用……省去你们大把查资料的时间= = 主要思想:把模块(文件)名.类名.方法名当成了变量 然后利用__import_ ...

  9. 如何将Win10 的环境变量页面设置用在win7上面?

    如何将Win10 的环境变量设置用在win7上面? Win7一般是如下设置: Win10 是如下设置: 解决办法: 注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentContr ...

  10. codeforces 761D - Dasha and Very Difficult Problem

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...