Redis专题——Redis的数据结构

redis有5种对外公开的数据结构,它们分别是string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合),实际上每种数据结构都有多种内部编码实现,这样redis就会在合适的场景选择合适的内部编码。

Redis专题——Redis的数据结构_第1张图片
redis的5种数据结构

可以用type key命令查询数据结构,用object encoding key命令查询内部编码。

Redis专题——Redis的数据结构_第2张图片
redis数据结构和内部编码

redis这样设计有两个好处:

  1. ,可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令,符合开闭原则
  2. 多种内部编码实现可以在不同场景下发挥各自的优势

string

string是redis最基础、最常用的数据结构,首先所有key都是string类型,而且其他几种数据结构都是在字符串类型基础上构建的,字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB

Redis专题——Redis的数据结构_第3张图片
内部编码

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

  • int:8个字节的长整型
  • embstr:小于等于39个字节的字符串
  • raw:大于39个字节的字符串
应用场景

string是redis最基本的数据结构,除了提供最基础的应用场景——缓存之外,还可以利用string的内部编码int进行计数,例如记录文章的点赞数阅读量等。

优化

hash

在Redis中,哈希类型是指键值本身又是一个键值对结构,形如key={{field1,value1},...{fieldN,valueN}}

Redis专题——Redis的数据结构_第4张图片
内部编码
  • ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。

  • hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

应用场景

相比于使用字符串序列化缓存信息,哈希类型变得更加直观,并且在更新操作上会更加便捷。所以一般需要频繁部分更新的缓存信息采用hash数据结构。

优化

list

列表(list)类型是用来存储多个有序的字符串,,列表中的每个字符串称为元素(element),一个列表最多可以存储个元素。在Redis中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是一种比较灵活的数据结构,可以充当栈和队列的角色。

Redis专题——Redis的数据结构_第5张图片
列表两端插入和弹出操作
Redis专题——Redis的数据结构_第6张图片
子列表获取、删除等操作

列表类型有两个特点:

  1. 列表中的元素是有序的,这就意味着可以通过索引下标获取某个元素或者某个范围内的元素列表。
  2. 列表中的元素可以是重复的。
内部编码
  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。
  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。
应用场景
  • 消息队列
    Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。

set

集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。,一个集合最多可以存储个元素。Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集

Redis专题——Redis的数据结构_第7张图片
内部编码
  • intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。
  • hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。
应用场景

集合类型比较典型的使用场景是标签(tag)。例如一个用户可能对娱乐、体育比较感兴趣,另一个用户可能对历史、新闻比较感兴趣,这些兴趣点就是标签。有了这些数据就可以得到喜欢同一个标签的人,以及用户的共同喜好的标签,这些数据对于用户体验以及增强用户黏度比较重要。例如一个电子商务的网站会对不同标签的用户做不同类型的推荐,比如对数码产品比较感兴趣的人,在各个页面或者通过邮件的形式给他们推荐最新的数码产品,通常会为网站带来更多的利益。

优化

zset

有序集合它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和list列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据。有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助我们在实际开发中解决很多问题。

Redis专题——Redis的数据结构_第8张图片
内部编码
  • ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用。
  • skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降。
应用场景

有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用户上传的视频做排行榜,榜单的维度可能是多个方面的:按照时间、按照播放数量、按照获得的赞数。

参考文献:
《Redis开发与运维》——付磊

你可能感兴趣的:(Redis专题——Redis的数据结构)