Redis字典的底层实现
2018-03-06 17:07
218 查看
redis的字典数据结构设计是最让我觉得精巧的,因为研究过HashMap的源码,一开始并没有觉得到底有什么优秀的地方,也无非就是,数组+链表的形式,但是不同的是在dict这个数据结构中有两张Hash表,一张用来存储,另一张用来做rehash。
先简单说说Hash表的实现方式,就是数组+链表,当要插入或者删除的时候先用一种高级的hash算法求出key的hash值(用的是MurmurHash2算法),然后用 hash值&dict->ht[x].sizemask得到索引下标 (sizemask掩码的大小是数组大小减一,数组大小始终是2的n次方,这些都与HashMap的实现相同),如果插入的时候发生了键冲突的话,就会采用链地址法,用头插法将其插入链表的头部(这样效率比较高)
因为redis讲求高效的存储和插入性能,所以redis对于rehash采用了及其精巧的rehash操作,我这是rehash最让人惊喜的一个地方。
一般来说会在负载因子大于等于五的时候尽行rehash(负载因子=哈希表已经保存的节点数/数组的长度)
渐进式rehash:在redis的字典中,rehash操作不是一步完成的而是渐进式的完成的,因为redis是一个讲求高效率存储和查找的nosql型数据库,而如果Hash表中的元素太多,那么rehash就要进行大量的计算,这样会导致效率降低,所以redis的字典采用了渐进式的rehash操作:
1. 先为ht[1](用来做rehash的表)分配空间,大小>=大于等于原来的hash表数组大小*2的2的整数次方。
2. 在字典中维护一个rehashidx变量,没有rehash的时候这个变量的值是-1,开始rehash的时候它就改成0,
3. 每当对原来的hash表(也就是ht[0]),进行增删改查操作的时候,都会讲hash表中数组下标为rehashidx的那一串链表进行rehash到ht[1]中,当前的rehash完成后rehashidx会增加一。
4. 随着字典操作的不断进行最终会rehash完成所有的ht[0],然后将rehashidx重新弄写成-1,并将ht[0]释放空间,将ht[0]=ht[1],ht[1]=null;
渐进式rehash执行期间的哈希表操作,查找、删除、修改会在两个表中进行(因为两个表都有数据嘛),但是增加操作只在ht[0]中尽行。
先简单说说Hash表的实现方式,就是数组+链表,当要插入或者删除的时候先用一种高级的hash算法求出key的hash值(用的是MurmurHash2算法),然后用 hash值&dict->ht[x].sizemask得到索引下标 (sizemask掩码的大小是数组大小减一,数组大小始终是2的n次方,这些都与HashMap的实现相同),如果插入的时候发生了键冲突的话,就会采用链地址法,用头插法将其插入链表的头部(这样效率比较高)
因为redis讲求高效的存储和插入性能,所以redis对于rehash采用了及其精巧的rehash操作,我这是rehash最让人惊喜的一个地方。
一般来说会在负载因子大于等于五的时候尽行rehash(负载因子=哈希表已经保存的节点数/数组的长度)
渐进式rehash:在redis的字典中,rehash操作不是一步完成的而是渐进式的完成的,因为redis是一个讲求高效率存储和查找的nosql型数据库,而如果Hash表中的元素太多,那么rehash就要进行大量的计算,这样会导致效率降低,所以redis的字典采用了渐进式的rehash操作:
1. 先为ht[1](用来做rehash的表)分配空间,大小>=大于等于原来的hash表数组大小*2的2的整数次方。
2. 在字典中维护一个rehashidx变量,没有rehash的时候这个变量的值是-1,开始rehash的时候它就改成0,
3. 每当对原来的hash表(也就是ht[0]),进行增删改查操作的时候,都会讲hash表中数组下标为rehashidx的那一串链表进行rehash到ht[1]中,当前的rehash完成后rehashidx会增加一。
4. 随着字典操作的不断进行最终会rehash完成所有的ht[0],然后将rehashidx重新弄写成-1,并将ht[0]释放空间,将ht[0]=ht[1],ht[1]=null;
渐进式rehash执行期间的哈希表操作,查找、删除、修改会在两个表中进行(因为两个表都有数据嘛),但是增加操作只在ht[0]中尽行。
相关文章推荐
- redis字典的底层实现hashTable
- redis底层数据结构之dict 字典2
- Redis的五种对象类型及其底层实现
- 【Redis基本数据结构】字典实现
- Redis源码阅读笔记(2)——字典(Map)实现原理
- 深入redis内部--字典实现
- redis源码分析 dict字典的实现和内部应用
- ssdb底层实现——ssdb底层是leveldb,leveldb根本上是skiplist(例如为存储多个list items,必然有多个item key,而非暴力string cat),用它来做redis的list和set等,势必在数据结构和算法层面上有诸多不适
- 【Redis】初探dict字典原理的实现(二)
- Redis 一、数据结构与对象--五大数据类型的底层结构实现
- 【Redis】初探dict字典原理的实现(一)
- Redis底层数据结构之字典
- Redis数据对象及底层编码实现
- redis字典的实现
- Redis 字典的实现(1)
- redis列表键的底层实现之链表
- Redis的设计与实现——字典
- Redis基础结构之hashtable(字典实现)
- Redis学习笔记(十五)Redis数据类型底层编码和实现原理
- Redis 字典的实现