Redis-字典源码内部原理解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zanpengfei/article/details/86518648

 1、dict是Redis服务器中出现最为频繁的复合型数据结构,用到地方很多,例如hash结构,整个Redis所有key和value组成一个全局的字典、带过期时间的key集合、zset集合汇总存储value和score直接映射关系等等

1)结构体:

struct RedisDb {

    dict* dict; // all keys  key=>value

    dict* expires; // all expired keys key=>long(timestamp)

    ...

}

 

struct zset {

    dict *dict; // all values  value=>score

    zskiplist *zsl;

}

2)dict内部结构

解析:如上图可以看出,dict结构内部包含俩个hashtable,通常只有一个是有值的。但是在扩容缩融的时候,需要分配一个新的hashtable,然后进行渐进式搬迁,搬迁结束后,旧的hashtable被删除。

      而hashTable的结构类似于hashMap结构,内部由数组+链表组成,通过分桶的方式姐姐hash冲突,数组中关联链表第一个元素的指针。具体结构如下图所示

struct dict {

    ...

    dictht ht[2];

}

而dictht结构如下:

struct dictht {

    dictEntry** table; // 二维

    long size; // 第一维数组的长度

    long used; // hash 表中的元素个数

    ...

}

struct dictEntry {

    void* key;

    void* val;

    dictEntry* next; // 链接下一个 entry

}

2、渐进式rehash

由于大字典的扩容比较耗时间,要将旧的链表下的数据重新挂到新的链表下,式O(n)级别的操作,所有Redis采用渐进式的rehash方式搬迁。

1)Redis的扩容分为2种,一种是客户端触发,另一种是定时任务中对字典进行主动搬迁

2)客户端触发搬迁过程:

首页判断是否需要扩容,若是,则小步搬迁;然后判断是否正在搬迁,是则将元素挂到新的分组下。

3)定时任务主动搬迁过程:

3、查找过程

func get(key) {

    let index = hash_func(key) % size;

    let entry = table[index];

    while(entry != NULL) {

        if entry.key == target {

            return entry.value;

        }

        entry = entry.next;

    }

}

解析:将key映射成一个整数,该整数对大小取余,得到位于那个桶下面,然后在该桶下面遍历获取与key相同的对应的value,最后将该value返回,其实与获取hashMap的操作类似。

4、hash韩素

hashtable性能完全取决于hash函数的质量,如果hash函数可以将key打算的表均匀,防止热key的产生,那么该hash函数就比较好,而hash函数默认是siphash算法,该算法即使在key很小的情况下,能够产生随机性特别好的输出

5、hash攻击

      hash攻击指的是hash函数在存在偏向性,黑客利用这个特点对服务器进行攻击,在这种情况下输入会导致hash的第二维链表长度极为不均匀,很有可能所有的元素都集中在个别的链表下,导致查找效率特别的低下,从而导致服务器就会被测底拖垮

6、扩容条件

正常情况下,当hash表中元素的个数等于第一维数组的长度时,就会开始扩容,扩容的大小是原数组的2倍,但如果Redis正在做bgsave,为了减少内存页的过多分离,Redis尽量不扩容(dict_can_resize),但如果hash表元素的个数已经达到数组大小的5倍(dict_force_resize_ratio),这时就要强制扩容

7、缩容

缩容的条件是元素的个数小于数组长度的10%,但缩容不会考虑bgsave是否在进行。

8、set结构

Redis 里面 set 的结构底层实现也是字典,只不过所有的 value 都是 NULL,其它的特性和字典一模一样。

猜你喜欢

转载自blog.csdn.net/zanpengfei/article/details/86518648
今日推荐