redis的数据结构及数据类型

string(字符串),字符串是最基本类型,所有的键都是字符串类型,字符串之外的其他几种复杂类型的元素也是字符串。字符串长度不能超过512M。字符串内部有3种编码:

int:8个字节的长整型

embstr:<=39字节的字符串。embstr与raw都使用RedisObject和SDS保存数据。区别在于:embstr的使用只分配一次内存空间(因此RedisObject和SDS是连续的),而raw需要分配两次内存空间(分别为RedisObject和SDS分配空间)。因此与raw相比,embstr的好处在于创建时少分配一次空间、删除时少释放一次空间、对象的所有数据连在一起,寻找方便。而embstr的坏处也很明显:如果字符串的长度增加需要重新分配内存时,整个RedisObject和SDS都需要重新分配空间,因此Redis中的embstr实现为只读。

raw:大于39个字节的字符串

embstr和raw进行区分的长度是39是因为RedisObject的长度是16字节,SDS的长度是9+字符串长度.因此当字符串长度是39时,embstr的长度正好是16+9+39=64,jemalloc正好可以分配64字节的内存单元。

当int数据不再是整数,或大小超过了long的范围时,自动转化为raw。

而对于embstr,由于其实现是只读的,因此在对embstr对象进行修改时,都会先转化为raw再进行修改,因此,只要是修改embstr对象,修改后的对象一定是raw的,无论是否达到了39个字节

list(列表),用来存储多个有序的字符串,每个字符串称为元素;一个列表可以存储2^32-1个元素。Redis中的列表支持两端插入和弹出,并可以获得指定位置(或范围)的元素,可以充当数组、队列、栈等。列表的内部编码可以是压缩列表(ziplist)或双端链表(linkedlist)

双端链表:由一个list结构和多个listNode结构组成

压缩列表:压缩列表是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块(而不是像双端链表一样每个节点是指针)组成的顺序型数据结构

只有同时满足下面两个条件时,才会使用压缩列表:

列表中元素数量小于512个;

列表中所有字符串对象都不足64字节。

set(集合),集合(set)与列表类似,都是用来保存多个字符串,但集合与列表有两点不同:集合中的元素是无序的,因此不能通过索引来操作元素;集合中的元素不能有重复

一个集合中最多可以存储2^32-1个元素,除了支持常规的增删改查,Redis还支持多个集合取交集、并集、差集。

集合的内部编码可以是整数集合(intset)或哈希表(hashtable)。

只有同时满足下面两个条件时,集合才会使用整数集合:

集合中元素数量小于512个;

集合中所有元素都是整数值。

zset(有序集合),有序集合与集合一样,元素都不能重复。但与集合不同的是,有序集合中的元素是有顺序的。与列表使用索引下标作为排序依据不同,有序集合为每个元素设置一个分数(score)作为排序依据

有序集合的内部编码可以是压缩列表(ziplist)或跳跃表(skiplist)

只有同时满足下面两个条件时,才会使用压缩列表:

有序集合中元素数量小于128个;

有序集合中所有成员长度都不足64字节。

hash(哈希),哈希使用的内部编码可以是压缩列表(ziplist)和哈希表(hashtable)两种

hashtable:一个hashtable由1个dict结构、2个dictht结构、1个dictEntry指针数组(称为bucket)和多个dictEntry结构组成。

redis的数据结构及数据类型

Redis中的哈希之所以在dictht和dictEntry结构之外还有一个dict结构,一方面是为了适应不同类型的键值对,另一方面是为了rehash。

只有同时满足下面两个条件时,才会使用压缩列表:

哈希中元素数量小于512个;

哈希中所有键值对的键和值字符串长度都小于64字节。


分享到:


相關文章: