redis类型结构剖析

redis的几大类型

Redis 是一款基于内存的键值数据库,其底层数据结构决定了其高效的读写性能和灵活的数据操作能力。Redis 支持的数据结构包括字符串、哈希表、列表、集合和有序集合,下面分别介绍它们的底层数据结构原理以及应用场景分析。

字符串

Redis 的字符串是一个简单的字节数组,底层数据结构使用的是 SDS(Simple Dynamic String)动态字符串。SDS 通过预分配空间和惰性空间释放机制,避免了频繁的内存分配和释放操作,提高了字符串的效率。同时,SDS 支持在 O(1) 时间复杂度下进行字符串长度计算和字符串复制操作,保证了字符串操作的高效性。

应用场景:字符串是 Redis 最基本的数据结构,常用于缓存、计数器、分布式锁等场景。例如,可以使用字符串类型的 Redis Key 来缓存页面内容、用户信息等,使用字符串类型的 Redis Value 来存储计数器、分布式锁等数据。

SDS

SDS 既然是字符串,那么首先需要一个字符串指针;为了方便上层的接口调用,该结构还需要记录一些关键信息,如当前数据长度和剩余容量等,数据结构如下:
在这里插入图片描述

sds优势

1:O(1)复杂度获取字符串长度
2:杜绝缓冲区溢出
3:减少修改字符串时带来的内存重分配次数
4:二进制安全

哈希表

Redis 的哈希表是一个键值对集合,底层数据结构使用的是字典(Dictionary)。字典是一种高效的键值对查找结构,采用哈希算法将键映射到对应的值上,并使用链表处理哈希冲突。Redis 的字典实现采用了渐进式 rehash 策略,可以在不影响 Redis 服务的情况下,动态扩容和缩容哈希表,保证了哈希表操作的高效性和灵活性。

应用场景:哈希表常用于存储对象属性、用户信息等场景。例如,可以使用哈希表类型的 Redis Key 来存储用户信息、对象属性等数据,使用哈希表类型的 Redis Value 来存储键值对数据。

对于Hash与zSet 集合,其底层的实现实际有两种:压缩列表 zipList,与跳跃列表 skipList。这两种实现对于用户来说是透明的,但用户写入不同的数据,系统会自动使用不同的实现只有同时满足以配置文件 redis.conf 中相关集合元素数量阅值与元素大小阅值两个条件,使用的就是压缩列表 zipList,只要有一个条件不满足使用的就是跳跃列表 skipList。例如,对于ZSet 集合中这两个条件如下:“
集合元素个数小于 redis.conf 中 zset-max-ziplist-entries 属性的值,其默认值为 128每个集合元素大小都小于 redis.conf 中 zset-max-ziplist-value 属性的值,其默认值为 64字节。
CSDN @pigOgo

ziplist
在这里插入图片描述
skipList
在这里插入图片描述
对于 ziplist,实现复杂,为了逆序遍历,每个 entry 中包含前一个entry 的长度,这样会导致在 ziplist 中间修改或者插入 entry 时需要进行级联更新。在高并发的写操作场景下会极度降低 Redis 的性能。为了实现更紧凑、更快的解析,更简单的实现,重写实现了 ziplist,并命名为 listPack。+
在 Redis 7.0 中,已经将 ipList 全部替换为了 listPack,但为了兼容性,在配置中也保留zipList 的相关属性。“CSDN @pig0go

listPack
在这里插入图片描述

列表

Redis 的列表是一个有序的字符串集合,底层数据结构使用的是双向链表(Linked List)。双向链表通过指针连接每个节点,可以支持在 O(1) 时间复杂度下进行节点的插入、删除和移动操作,保证了列表操作的高效性。同时,Redis 的列表还支持快速的索引访问和范围访问操作,提高了列表的灵活性。

应用场景:列表常用于存储队列、栈、历史记录等场景。例如,可以使用列表类型的 Redis Key 来存储消息队列、操作历史等数据,使用列表类型的 Redis Value 来存储有序字符串数据。

quickList,快速列表,quickList 本身是一个双向无循环链表,它的每一个节点都是一个zipList。从Redis3.2版本开始,对于List的底层实现,使用quickList替代了zipList 和 linkedList。zipList 与 linkedList 都存在有明显不足,而 quickList 则对它们进行了改进:吸取了 zipList和 linkedList 的优点,避开了它们的不足。
quickList 本质上是 ipList 和 inkedList 的混合体。其将 linkedList 按段切分,每一段使用 zipList 来紧凑存储若干真正的数据元素,多个 zipList 之间使用双向指针串接起来。当然对于每个 zipList 中最多可存放多大容量的数据元素,在配置文件中通过 list-max-ziplist-size属性可以指定。

quickList
在这里插入图片描述

集合

Redis 的集合是一个无序的字符串集合,底层数据结构使用的是哈希表。哈希表可以在 O(1) 时间复杂度下进行元素的查找、插入、删除操作,保证了集合操作的高效性。同时,Redis 的集合还支持交集、并集、差集等集合操作,提高了集合的灵活性。

应用场景:集合常用于存储无序的唯一元素、标签、好友等场景。例如,可以使用集合类型的 Redis Key 来存储用户的好友列表、文章的标签列表等数据,使用集合类型的 Redis Value 来存储唯一字符串数据。

有序集合

Redis 的有序集合是一个有序的字符串集合,底层数据结构使用的是跳跃表(Skip List)。跳跃表是一种高效的有序数据结构,可以在 O(log n) 时间复杂度下进行元素的查找、插入、删除操作,保证了有序集合操作的高效性。同时,Redis 的有序集合还支持按照分值(Score)范围进行元素的范围查找、排名等操作,提高了有序集合的灵活性。

应用场景:有序集合常用于存储排行榜、时间轴、热门文章等场景。例如,可以使用有序集合类型的 Redis Key 来存储用户的积分排行榜、文章的发布时间轴等数据,使用有序集合类型的 Redis Value 来存储带有分值的字符串数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值