Redis数据结构之字典

目录

字典的应用场景

源码实现

hash算法的实现, hash冲突的解决

扩容缩容机制

哈希表的扩展与收缩条件

渐进式rehash

线程是否安全

Redis的dictht 和 Java(jdk1.8)的HashMap有什么区别

线程安全性

hash算法

解决hash冲突的方法

扩容机制


 

字典的应用场景

1.redis数据库本身的实现就是 字典,因为redis本身就是 kv存储的。

2.redis数据结构中的Set也是用了字典。
 

Redis数据结构之字典_第1张图片

源码实现

和Java类似,也是 table ,entry等数据结构。

Redis数据结构之字典_第2张图片

Redis数据结构之字典_第3张图片Redis数据结构之字典_第4张图片

当字典被用作数据库的底层实现,或者哈希键的底层实现时,Redis使用MurmurHash2
算法来计算键的哈希值。
MurmurHash算法最初由Austin Appleby于2008年发明,这种算法的优点在于,即使
输人的键是有规律的,算法仍能给出一个很好的随机分布性,并且算法的计算速度也非常快。
MurmurHash算法目前的最新版本为MurmurHash3,而Redis使用的是MurmurHash.2。

 

说到字典,总会涉及到几个问题,比如hash算法的实现,怎么解决hash冲突的,存取的效率如何,扩容机制是怎样的。

hash算法的实现, hash冲突的解决

hash算法是MurmurHash2, 解决hash冲突的方法是链地址法,和Java的HashMap一样, 不过采用的是头插法。

扩容缩容机制

table0 是当前数据存储的表,redis中还有一个table1,就是用来进行扩容和缩容的,

如果执行的是扩展操作,那么table1的大小变为第一个大于等于table0 大小*2的n次方幂;
如果执行的是收缩操作,那么table1的大小变为第一个大于等于table0 大小的2的n次方幂。

也就是说redis的table中桶的数量总是2的n次方幂。

然后再对table0中的所有元素进行rehash,存储到table1上面,之后令table0 = table1,table1新创建一个空白的hash表。

哈希表的扩展与收缩条件

当以下条件中的任意一个被满足时,程序会自动开始对哈希表执行扩展操作:


1)服务器目前没有在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负
载因子大于等于1.
2)服务器目前正在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载
因子大于等于5。

因为这个时候子进程使用写时复制正在进行持久化操作,希望尽可能的不要rehash,不然在rehash的时候会占用更多的内存。

Redis数据结构之字典_第5张图片

渐进式rehash

为了避免大量键值对的rehash对服务器性能造成影响,服务器不是一次性将table0里面的所有
键值对全部rehash到table1,而是分多次、渐进式地将table0里面的键值对慢慢地rehash
到table1。

Redis数据结构之字典_第6张图片

线程是否安全

Redis Server本身是一个线程安全的K-V数据库,Redis Server中的指令执行是原子的,也就是说在Redis Server上执行的指令,不需要任何同步机制,不会存在线程安全问题。

Redis的dictht 和 Java(jdk1.8)的HashMap有什么区别

线程安全性

Java不是线程安全的,Redis是。

hash算法

Java:

生成一个随机数作为hashcode,当然可以重写自己的hashcode方法。

 Redis数据结构之字典_第7张图片

 java默认的hashcode方法到底得到的是什么?_hb1993的博客-CSDN博客_java 默认hashcode

Redis:

MurmurHash2

解决hash冲突的方法

都是链地址法,但Redis是头插,Java是尾插。

扩容机制

初始容量和扩容机制也不相同,比如负载因子等。

你可能感兴趣的:(Redis,redis,数据结构,哈希算法)