我们先来看redis五大数据类型,string、list、hash、set、zset
再来看下redis五大数据类型用到的数据结构
- 压缩列表(ziplist):压缩列表可以看做是特殊的数组,它也是通过一片连续的存储空间来存储数据的。但与数组要求每个元素占用的空间大小一致不同,压缩列表允许存储元素的大小不同。存储格式为[data_num][data1_len][data1][data2_len][data_2][...],data_num表示了压缩列表存储的数据数目,datai_len代表第i个数据项的长度,datai则表示具体存储的数据。压缩列表这样存储结构,一方面节省内存,一方面允许不同类型的数据的存储,比数组灵活。
- 整数数组(intset)
- 双向链表(linkedlist)
- 散列表(hashtable):采用MurmuerHash2哈希算法实现,该哈希算法有运行速度快、随机性好的特点。Redis采用链表法来解决哈希冲突。除此之外,Redis支持动态扩容、缩容。当哈希表的数据增多,会导致哈希冲突的链表过长,进一步导致查找效率降低,此时哈希表会扩容。反之进行缩容。具体做法为Redis 默认使用了两个全局哈希表:哈希表 1 和哈希表 2。一开始,当你刚插入数据时,默认使用哈希表 1,此时的哈希表 2 并没有被分配空间,当进行rehash时,给哈希表 2 分配更大的空间,例如是当前哈希表 1 大小的两倍,然后把哈希表 1 中的数据重新映射并拷贝到哈希表 2 中,最后释放哈希表1的空间。
- 跳跃表(skiplist):之前介绍过,一个多层的有序链表,感兴趣的可以前去观看https://www.jianshu.com/p/fd233a9d5a87
整数数组和双向链表相信大家都比较熟悉,就不过多介绍了。
接下来我们看具体的数据类型对应的数据结构
string
string的底层实现可以是int、raw、embstr。int 编码是用来保存整数值,raw编码是用来保存长字符串,而embstr是用来保存短字符串。
int,存储 8 个字节的长整型(long,2^63-1)。
raw,存储大于 44 个字节的字符串(3.2 版本之前是 39 字节)
embstr, 代表 embstr 格式的 SDS(Simple Dynamic String 简单动态字符串),存储小于 44 个字节的字符串。
list
list底层的数据结构可以是ziplist和linkedlist,当列表对象保存的所有字符串元素的长度都小于64字节,且列表保存的元素少于512个,会使用ziplist,否则会使用linkedlist。
set
set的底层是intset或者hashtable,当集合对象保存的所有对象都是整数值,而且集合对象保存的元素数量小于512个,会使用intset,否则会使用hashtable。
hash
hash的底层是ziplist或者hashtable,当哈希对象保存的所有键值对的键和值的字符串长度都小于64字节,且哈希对象保存的键值对的数量小于512个,会使用ziplist,否则使用hashtable。
zset
zset的底层是ziplist或者skiplist,当有序集合的所有元素长度都小于64字节,且有序集合的元素数量小于128个,会使用ziplist,否则会使用skiplist。
总结
图1引用:
https://blog.csdn.net/qq_42956653/article/details/122508570
https://blog.csdn.net/Solo95/article/details/108968393
https://www.imooc.com/article/324827
网友评论