Redis-数据结构-RedisObject、字典

一、对象 redisObject

1、定义与结构

        redis使用对象来表示数据库中的键和值,对象包含字符串(string)、列表(list)、哈希(hash)、集合(set)、有序集合(z-set)5中类型。当在redis数据库中创建一个键值对时,至少创建两个对象,一个用作键(键对象),另一个用作值(值对象)。

        好处是:1)可以针对不同的使用场景,为对象设置多种不同的数据结构实现,从而优化不同场景下的使用效率。2)对象系统实现了基于引用计数的内存回收机制。3)通过引用计数实现了对象共享机制,在适当的条件下通过共享同一对象来节约内存。4)redis对象带有访问时间记录信息(最后访问的时间戳),在启动maxmemory功能的情况下,较长时间未访问的键可能会优先被服务器删除

        结构

        type值

        encoding值

二、字典

    1、定义与结构

        字典是一种用于保存键值对(key-value pair)的抽象数据结构。redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,每个节点保存一个键值对。

        1.1、哈希表

        1.2、哈希表节点


        键值对的值可以是 指针、uint64_t类型的整数、int64_t类型的整数、double类型的浮点数(源码版本5.05)

        1.3、字典

        type属性指向dictType结构的指针,每个dictType结构保存了一簇用于操作特定类型值的函数;

        privdata属性保存需要传给类型特定函数的可选参数;

        ht属性是一个包含两个项的数组,一般情况下只是用ht[0]哈希表,ht[1]只在rehash时使用;

        rehashidx 记录rehash的进度,如果没有进行rehash,则为-1


        1.4、Java 中 HashMap


2、哈希算法

        2.1、计算步骤

        1)使用字典设置的哈希函数,计算key的hash值       hash = dict -> type -> hashFunction(key);

        2)使用哈希表的sizemask属性和哈希值,计算索引值     index = hash & dict -> ht[x].sizemask;

        2.2、键冲突(哈希冲突)

        使用redis链地址法解决键冲突,每个哈希表节点都有一个next指针,索引相同的多个哈希表节点通过next构成一个单项链表,解决键冲突,并且总是将新节点添加到链表的表头位置

        2.3、rehash

        1)为字典的ht[1]分配空间,空间大小取决于要执行的操作和ht[0]当前键值对的数量(ht[0].userd属性)

                扩容操作,则为 大于等于 ht[0].userd*2 的最小的 2^n ;

                收缩操作,则为 大于等于 ht[0].used      的最小的 2^n;

        2) 将保存在ht[0]中的所有键值对rehash到ht[1]:重新计算键的hash值和索引值,然后将键值对存放到ht[1]指定的位置上

        3)释放ht[0](变为空表),将ht[1]设置为ht[0], ht[1]创建一个空白哈希表。

        2.3、渐进式rehash

        为了避免一次性rehash大量键值对造成的性能影响,redis分多次将ht[0]里的键值对rehash到ht[1]中。渐进式rehash的好处在于采取分而治之的方式,将rehash键值对所需计算工作均摊到对字典的每个添加、删除、查找、和更新操作上,避免了集中式rehash带来的庞大计算量。渐进式rehash执行期间字典会同时使用ht[0]和ht[1]两个哈希表,删除(delete)、查找(find)、更新(update)操作会在两个哈希表上进行,先在ht[0]上执行,如果没有结果,再在ht[1]上执行,最后返回结果;添加(add)操作一律保存到ht[1], ht[0]不进行任何操作,保证了ht[0]包含的键值对只减不增。

        1)为ht[1]分配空间,让字典同时持有ht[0]和ht[1]两个哈希表

        2)将字典中的索引计数器rehashidx的值设置为0,表示rehash开始

        3)在rehash期间,每次对字典执行添加、删除、查找或更新操作时,在ht[0]上执行操作之外,还会在将ht[0]在rehashidx索引位置上的所有键值对(节点)rehash到ht[1]上,当rehash工作完成之后,程序将rehashidx值+1;

        4)随着字典操作不断执行,当ht[0]的所有键值对都rehash到ht[1],设置 rehashidx = -1,表示rehash操作完成

你可能感兴趣的:(Redis-数据结构-RedisObject、字典)