问题
redis常见的数据类型 及 应用场景
五种基本类型
String:分布式锁、缓存对象、缓存sessionList:消息队列(但是有缺陷)Hash:缓存对象 、缓存购物车()Set无序集合:(并交差集的场景)共同好友,共同关注。还有抽奖(随机获取其中的元素)Zset(sorted set):排行榜,接口限流 等
String 的底层实现是什么?为什么实现了 SDS?
底层是int和SDS。
为什么实现了SDS?(答SDS的优点)
- SDS不仅可以保存文本数据,还可以保存二进制数据。(len属性值判断是否结束)
- SDS获取字符串长度时间复杂度为O(1)
- SDS API 是安全的,拼接字符串不会造成缓冲区溢出。(api在拼接字符时会检查空间是否满足要求)
- 不同的SDS类型,len和alloc字段使用的数据类型也不同。
- SDS支持动态扩容。
Zset有什么应用场景?项目哪里用到了?
Zset类似于一个有序集合,每个集合元素有一个score,按score排序。(底层使用压缩列表或跳表)
应用场景:
- 排行榜:各种排行榜。学生成绩、视频播放、博文点赞。
- zset滑动窗口限流。【Redis Lua脚本 分布式限流 窗口 令牌桶 漏桶】_redis 令牌桶-CSDN博客
Redis--Zset使用场景举例(滑动窗口实现限流)_redis 滑动窗口-CSDN博客
概念
String
底层采用SDS和int,如果存普通数字就用int,字符采用SDS存
list
可以从队首 或者 队尾插入元素。也可以从 队首队尾 取出元素。(可用于消息队列)
lpush lpop rpush rpop
通过特点推断底层结构
为了支持双端访问,双向链表 和 压缩列表都支持双端访问,所以redis3.2之前用这两个结构实现。(为什么压缩列表支持可以看压缩列表的结构)
redis3.2 以后 底层结构仅为 quicklist。(quicklist其实就是压缩列表加双向链表的结合)
zset
Zset 类型(有序集合类型)相比于 Set 类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序集合的元素值,一个是排序值。
特点:1. 根据元素score 排序。2. member唯一。3.可以根据member查score
通过特点推断底层结构
底层结构:采用 跳表(用于排序) 或者 压缩列表/listpack 结构(用于排序) 。其实内部还有个哈希表为了满足根据member查score。
- 如果有序集合的元素个数小于 128 个,并且每个元素的值小于 64 字节时,Redis 会使用压缩列表作为 Zset 类型的底层数据结构;
- 如果有序集合的元素不满足上面的条件,Redis 会使用跳表作为 Zset 类型的底层数据结构;
- 在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。
在元素少的时候,用压缩列表/listpack 存也可以满足排序需求,查询的时候就一个个查嘛,反正元素少。并且元素少的时候用跳表还会占额外的空间。
在元素多的时候就要用跳表了,用来排序的,查找的时候更快。
set
保证元素唯一(不需要排序)。而且有判断元素是否存在的功能。
通过特点推断底层结构
为了快速查找元素,使用Dict哈希表,当所有数据都是 整数且数据量不大时,使用intSet整数集合(intset数组内部其实是排好序的,查找的时候用二分查找,元素少二分查找效率也不低)。
在元素少且数据都是整数的时候,用intSet,查找就二分查找,节省空间。
在元素多的时候就要用Dict哈希表了,查找更快。
hash
在元素少的时候,用ZipList压缩列表 目前改为 listpack,节省空间。
在元素多的时候就要用Dict哈希表了,查找更快。