假装在面试(二):你知道Redis都有哪些数据结构。

在上一篇已经说到了,redis的五种对外的数据类型,也就是用户可以选择存储的数据类型。分别是:

string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)

但是如果面对这个问题,仅仅只回答这五种数据类型,显然是不够的。这个问题的本质还是在考验你是否对于redis的每一种数据类型都足够了解,因为只有你深入了解了这些数据类型的结构和redis对它的实现,你才可以在很多场景下清楚的知道你要如何优化你的redis服务。

在redis的内部,上述的五种数据结构都至少有两种以上的内部编码实现,同一种数据结构,实现的编码不同,查询的速度和消耗的内存大小是不同的。所以,了解redis五种类型的内部数据结构实现,就能更好的权衡实际生产场景中应该如何存储你的数据,以达到你想要的优化效果。或是快速的存储,或是想要更有效的利用内存节约资源成本。

下面是redis的五种数据结构所有的内部编码,如图:

在这里插入图片描述
你可以通过 object encoding key 命令来查询一个key在redis内部的实现编码。

字符串

字符串对象是Redis内部最常用的数据类型。所有的键都是字符串类型,值对象数据除了整数之外都使用字符串存储。

在redis内部字符串类型的内部编码有3种:

int:8个字节的长整型
embstr:小于等于39个字节的字符串
raw:大于39个字节的字符串

Redis会根据当前值的类型和长度决定使用哪种内部编码实现。查看redis字符串实现详细讲解。

表与集合

redis的表和集合有许多相同的编码实现,下面我全部列出来。

ziplist : 压缩列表
hashtable : 哈希表
linkedlist: 链表
intset : 整数集合
skiplist : 跳跃表

关于这五种数据结构的实现可以看下面这几篇文章:
redis中ziplist实现详细讲解(目前还未写完)
redis中hashtable实现详细讲解(目前还未写完)
redis中linkedlist实现详细讲解(目前还未写完)
redis中intset实现详细讲解(目前还未写完)
redis中skiplist实现详细讲解(目前还未写完)

下面我们来看这些数据结构都有些什么优势。

ziplist:ziplist编码设计出来的主要目的是为了节约内存。它的所有数据都是采用线性连续的内存结构,它redis内应用范围最广的一种编码,可以分别作为hash,ist,zset类型的底层数据结构实现。
优点:内存消耗小。
缺点:查询数据的时间复杂度高O(n)。

hashtable:hashtable是hash表实现源码之一,hash表有很快的查询速度O(1),但是由于没有压缩数据,消耗的内存远远大于ziplist编码。
优点:查询速度极快。
缺点:消耗更多的内存。

linkedlist:linkedlist是list列表的实现源码之一,它是一个双向链表,每个节点还存储了前驱节点和后继节点的地址指针。链表的优势在于插入的时间复杂度是O(1),虽然随机访问的时间复杂度是O(n),但是redis的list结构不需要随机访问,固定的从列表头提取数据,所以速度很快。同样的,它比ziplist消耗的内存更多。 优点:插入速度极快。
缺点:消耗更多的内存。

intset: intset编码是set实现编码的一种,intset编码的特点是有序的存储了不重复的整数类型。

优点:由于是有序集合,集合内查找特定的元素使用二分查找只需要log(n)的时间复杂度。
缺点:只能存储整型元素,而且插入的时候会对元素进行排序,时间复杂度O(n)。

skiplist :skiplist编码是zset有序列表实现编码的一种,skiplist底层由hash表加上跳跃表来实现。主要的思路是用跳跃表插入和查询的时间复杂度都很快(具体取决于每级索引间隔的数据量),而且跳跃表的区间查询的速度也是极快的。缺点依旧是相比ziplist来说,内存消耗大的多。

优点:查询速度快。
缺点:内存消耗多。

介绍完了redis内部的五种数据结构,那么这些结构的优点缺点就一目了然。redis可以通过配置来控制内部编码的实现。也就是说,你可以通过配置控制你的数据的内部存储结构,以达到你想要的效果。

如果你的业务是非I/O密集型,意味着查询速度并不会很影响你的业务。所以你可能更加关注redis的内存消耗,希望你存储的数据消耗更少的内存以降低内存成本。那么你应该更多的使用ziplist来存储你的数据(redis是内存存取,虽然相对其他数据结构查询较慢,但是相对硬件存取的速度也是很快的)。

反过来,如果你的业务是高并发的业务,需要极速响应,很在乎查询的时间,那么你就不应当用ziplist存储你的数据。使用更大的内存来换取查询的速度,使你的业务更加流畅。

下面是关于ziplist的配置:
在这里插入图片描述
在redis-cli中使用 set 参数名 数量 命令,就可以配置相应的参数。

需要注意的是,ziplist可以向更复杂的数据内心转换,但是不支持回退到ziplist类型。因为数据增删频繁的时候,数据压缩非常的小号CPU资源,得不偿失。

所以如果已经存储的数据,如果想要以ziplist存储,需要修改配置之后,重新存储一遍才行。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值