一口气讲完了 Redis 常用的数据结构及应用场景
一、概述
Redis
是互联网技术领域使用最为广泛的存储中间件,它是Remote Dictionary Service(远程字典服务)
的首字母缩写,Redis
以其超高的性能、活跃的社区、详细的文档以及丰富的客户端库支持在开源中间件领域广受好评,国内外很多大型互联网都在使用Redis
,比如:Github
、新浪微博、阿里巴巴、京东、Stack Overflow
等,可以说,深入了解Redis
应用和实践,已成为如今中高级后端加法绕不开的必备技能。
二、Redis 常见应用场景
三、Redis 有哪些数据结构
3.1 String 字符串
🔥字符串典型的使用场景:
单值缓存
对象缓存
计数器
分布式锁
单值缓存
单值缓存
计数器
文章阅读量、点赞量、评论量
分布式锁
setnx
定时任务防止同一时刻重复执行,可以在业务执行代码前使用分布式锁控制。
伪代码如下:
setex + 过期时间【SETNX KEY_NAME TIMEOUT VALUE】
hash 哈希
🔥哈希典型应用场景:
缓存对象信息(帖子标题、摘要、作者信息)
记录帖子的点赞数、评论数和点击数
电商购物车
list 列表
🔥列表的典型应用场景:
文章列表
微博和微信公众号消息
set 集合
🔥列表的典型应用场景:
抽奖
微博点赞,收藏,标签
共同好友
抽奖场景:
用户参与抽奖
查看参与商品 a 抽奖的所有用户
抽取 1 名幸运中奖者
共同好友场景:
用户 1 的好友为:3,4,8 用户 2 的好友为:4,5,11
取交集,获取用户 1 和用户 2 的共同好友,为用户 4。
sorted set 有序集合
🔥列表的典型应用场景:
微博热搜榜
刷礼物实时排行榜
博客社区本周热议
Redis
有序集合和集合一样也是string
类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double
类型的分数,Redis
正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数score
却可以重复。下面使用redis-cli
实践Redis
有序集合命令:
zset 几个基本命令:
简单认识了Redis
有序集合和对应的命令之后,我们来实现本周热议排行榜功能,博客的本周热议主要的实现思路是:
库获取最近 7 天的所有文章(或者加多一个条件:评论数量大于 0)。
把文章的评论数量作为有序集合的分数
score
,文章的 ID 作为key
存储到zset
中,当有人发表评论的时候,直接使用命令加一,并重新计算得到排行榜。本周热议上有标题和评论数量,因此,我们还需要把文章的基本信息存储到
Redis
中,这样得到文章的 ID 之后,我们再从缓存中得到标题等信息,这里我们可以使用hash
的结构来存储文章的信息。因为是本周热议,如果文章发表超过 7 天了之后就会失效,所以我们可以给文章的有序集合一个有效时间。超过 7 天之后就自动删除缓存。
画图分析:
最终实现效果:
Bitmaps 位图
🔥位图的典型应用场景:
用户连续签到功能
很多社区、博客平台其实都有每日签到模块,一开始看到这个模块需求的时候,很多人第一反应是利用MySQL
来实现,创建一个签到表,记录用户 ID 和签到时间,然后统计的时候从数据库中取出来然后聚合计算,这样设计其实存在弊端,如我们想要做一些复杂的功能就不是太方便了,或者说不是太高性能了,比如,今天是连续签到的第几天,在一定时间内连续签到了多少天。另外一方面,如果按 100 万用户量级来计算,一个用户每年可以产生 365 条记录,100 万用户的所有签到记录那就有点恐怖了,查询计算速度也会越来越慢。其实Redis
的Bitmaps
位图操作非常适合处理每日签到功能场景,因为 Bit 的值为 0 或者 1,位图的每一位代表一天的签到,1 表示已签,0 表示未签。 考虑到每月初需要重置连续签到次数,最简单的方式是按用户每月存一条签到数据(也可以每年存一条数据)。Key 的格式为u:sign:uid:yyyyMM
,Value 则采用长度为 4 个字节(32 位)的位图(最大月份只有 31 天)。
Redis 位图命令基本命令
这里的 offset,大家姑且当做用户 ID 来看就可以了,那么究竟如何去实现用户打卡功能呢,我们可以利用上面的setbit
命令来实现,setbit
的作用说的直白就是:在你想要的位置操作字节值,比如说u:sign:1000:202302
表示ID=1000
的用户在2023年2月7号
签到记录。
示例代码:
运行结果:
Redis 发布订阅
Redis 提供了发布订阅功能,可以用于消息的传输,Redis 的发布订阅机制包括三个部分:发布者
、订阅者
和Channel
。发布者和订阅者都是 Redis 客户端,Channel 则为 Redis 服务器端,发布者将消息发送到某个的频道,订阅了这个频道的订阅者就能接收到这条消息。Redis 的这种发布订阅机制与基于主题的发布订阅类似,Channel 相当于主题。
评论