Redis深入之数据结构

时间:2020-12-03 07:43:09

Redis主要数据结构

链表

Redis使用的C语言并没有内置这样的数据结构,所以Redis构建了自己的链表实现。列表键的底层实现之中的一个就是链表,一个列表键包括了数量比較多的元素,列表中包括的元素都是比較长的字符串,Redis就会使用链表作为列表键的底层实现。

除了链表键之外。Redisserver本身还使用链表来保存多个client的状态信息。使用链表来构建client输出缓冲区。

eg: redis> LLEN integers

(integer)1024

integers列表键包括了从1到1024共1024个整数,integers列表键的底层实现就是一个链表,链表中的每一个节点都保存了一个整数值。

每一个链表节点由一个listNode结构来表示,每一个节点都有一个指向前置节点和后置节点的指针。Redis的链表实现是双端链表。

每一个链表使用一个list结构来表示,这个结构带有表头节点指针、表尾节点指针,以及链表长度等。

由于链表表头节点的前置节点和表尾节点的后置节点都指向NULL,所以Redis的链表实现是无环链表。

字典

字典。符号表或映射,保存键值对的抽象数据结构

Redis构建了自己的字典。字典使用哈希表作为底层实现,每一个字典带有两个哈希表。一个平时使用,还有一个仅在进行rehash时使用。一个哈希表里面能够有多个哈希表节点。而每一个哈希表节点就保存了字典中的一个键值对。Redis使用MurmurHash2算法来计算键的哈希值。

两个或以上数量的键被分配到了哈希表数组的同一个索引上面。这些键发生了冲突。Redis的哈希表使用链地址法来解决键冲突。

随着操作的不断运行,哈希表保存的键值对会逐渐地增多或者降低。为了让哈希表的负载因子维持在一个合理的范围之内,扩展和收缩哈希表的工作能够通过运行rehash(又一次散列)操作来完毕,须要将现有哈希表包括的全部键值对rehash到新哈希表里面。而且rehash过程并非一次性完毕的,而是渐进式地完毕的。

跳跃表

跳跃表是一种有序数据结构,它通过在每一个节点中维持多个指向其他节点的指针。从而达到高速訪问节点的目的。

redis>ZRANGE fruit-price 0 2 WITHSCORES

fruit-price有序集合的全部数据都保存在一个跳跃表里面,每一个跳跃表节点都保存了一款水果的价钱信息,全部水果按价钱的高低从低到高在跳跃表里面排序。

Redis使用跳跃表作为有序集合键的底层实现之中的一个,假设一个有序集合包括的元素数量比較多。又或者有序集合中元素成员是比較长的字符串时。Redis就会使用跳跃表来作为有序集合键的底层实现。Redis仅仅在两个地方用到了跳跃表。一个是实现有序集合键。还有一个是在集群节点中用作内部数据结构。

Redis的跳跃表实现由zskiplist和zskiplistNode两个结构组成,当中zskiplist用于保存跳跃表信息(比方表头节点、表尾节点、长度)。而zskiplistNode则用于表示跳跃表节点。

整数集合

整数集合是集合键的底层实现之中的一个,当一个集合仅仅包括整数值元素,而且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现。

redis > SADD numbers 1 3 5 7 9

压缩列表是一种为节约内存而开发的顺序型数据结构。

redis>RPUSH 1st 1 3 5 10086 "hello" "world"

压缩列表由一系列特殊编码的连续内存块组成的顺序型数据结构。

压缩列表被用作列表键和哈希键的底层实现之中的一个

压缩列表能够包括多个节点。每一个节点能够保存一个字节数组或者整数值。

加入新节点到压缩列表,或者从压缩列表中删除节点。可能会引发连锁更新操作,但这样的操作出现的几率并不高。