Redis源码研究—哈希表
2016-03-02 00:05
435 查看
1. Redis中的哈希表
前面提到Redis是个key/value存储系统,学过数据结构的人都知道,key/value最简单的数据结果就是哈希表(当然,还有其他方式,如B-树,二叉平衡树等),hash表的性能取决于两个因素:hash表的大小和解决冲突的方法。这两个是矛盾的:hash表大,则冲突少,但是用内存过大;而hash表小,则内存使用少,但冲突多,性能低。一个好的hash表会权衡这两个因素,使内存使用量和性能均尽可能低。在Redis中,哈希表是所有其他数据结构的基础,对于其他所有数据结构,如:string,set,sortedset,均是保存到hash表中的value中的,这个可以很容易的通过设置value的类型为void*做到。本文详细介绍了Redis中hash表的设计思想和实现方法。【注】 本文的源代码分析是基于redis-2.4.3版本的。
2. Redis哈希表的设计思想
下图是从淘宝《Redis内存存储结构分析》中摘得的图片,主要描述Redis中hash表的组织方式。![](http://dongxicheng.org/wp-content/uploads/2011/12/redis-dict.jpg)
在Redis中,hash表被称为字典(dictionary),采用了典型的链式解决冲突方法,即:当有多个key/value的key的映射值(每对key/value保存之前,会先通过类似HASH(key) MOD N的方法计算一个值,以便确定其对应的hash table的位置)相同时,会将这些value以单链表的形式保存;同时为了控制哈希表所占内存大小,redis采用了双哈希表(ht[2])结构,并逐步扩大哈希表容量(桶的大小)的策略,即:刚开始,哈希表ht[0]的桶大小为4,哈希表ht[1]的桶大小为0,待冲突严重(redis有一定的判断条件)后,ht[1]中桶的大小增为ht[0]的两倍,并逐步(注意这个词:”逐步”)将哈希表ht[0]中元素迁移(称为“再次Hash”)到ht[1],待ht[0]中所有元素全部迁移到ht[1]后,再将ht[1]交给ht[0](这里仅仅是C语言地址交换),之后重复上面的过程。
3. Redis哈希表实现
3.1 基本数据结构
Redis哈希表的实现位于文件dict.h和dict.c中,主要数据结构如下:3.2 基本操作
Redis中hash table主要有以下几个对外提供的接口:dictCreate、dictAdd、dictReplace、dictDelete、dictFind、dictEmpty等,而这些接口调用了一些基础操作,包括:_dictRehashStep,_dictKeyIndex等。下面分析一下_dictRehashStep函数:该函数主要完成rehash操作。Hash Table在一定情况下会触发rehash操作,即:将第一个hash table中的数据逐步转移到第二个hash table中。
【1】触发条件
【2】转移策略
为了避免一次性转移带来的开销,Redis采用了平摊开销的策略,即:将转移代价平摊到每个基本操作中,如:dictAdd、dictReplace、dictFind中,每执行一次这些基本操作会触发一个桶中元素的迁移操作。在此,有读者可能会问,如果这样的话,如果旧hash table非常大,什么时候才能迁移完。为了提高前移速度,Redis有一个周期性任务serverCron,每隔一段时间会迁移100个桶。
首先,检查hash table是否正在rehash操作,如果是,则分摊一个rehash开销:
< b964 div class="line number6 index5 alt1">6 |
原创文章,转载请注明: 转载自董的博客
本文链接地址: http://dongxicheng.org/nosql/redis-code-hashtable/
相关文章推荐
- Logstash+Redis+Elasticsearch+Kibana+Nginx搭建日志分析系统
- redis的安装
- redis单主机配置多实例
- redis的主从复制配置
- redis.conf 配置参数
- redis 与 jedis
- redis-windows 安装配置以及使用手册
- Redis 主从复制
- Redis : ServiceStack.Redis之IRedisClient
- Redis服务器搭建/配置/及Jedis客户端的使用方法
- Ubuntu下,卸载 / 安装Redis / 导出导入数据
- java redis使用参考文档
- redis持久化RDB和AOF
- 关于Redis中的list常见的操作
- C++自制Redis 数据库 (十五)【重构】数据库学习(一)
- java对redis的基本使用(Jedis)
- NoSQL初探之人人都爱Redis:(1)Redis简介与简单安装
- NoSQL初探之人人都爱Redis:(2)Redis API与常用数据类型简介
- NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例
- redis在tag订阅功能中的实践