Redis 常见使用场景
Redis 可以作为缓存热点数据(经常被查询,但是不经常被修改或者删除的数据)、分布式锁、数据库,和消息中间件等大部分功能。
缓存
String 类型
- 热点数据缓存
- 对象缓存
- 全页缓存
数据共享分布式
String 类型,因为 Redis 是分布式的独立服务,可以在多个应用之间共享
|
|
分布式锁
setnx方法,只有不存在时才能添加成功,返回true
INCR key
|
|
将存储的数字key加一。如果该键不存在,则0在执行操作之前将其设置为。如果键包含错误类型的值或包含无法表示为整数的字符串,则会返回错误。此操作仅限于 64 位有符号整数。
注意:这是一个字符串操作,因为 Redis 没有专用的整数类型。存储在密钥中的字符串被解释为以 base-10 的 64 位有符号整数以执行操作。
计数器 Counter
计数器模式是 Redis 原子增量操作可以做的最明显的事情。这个想法只是INCR在每次操作发生时向 Redis 发送一个命令。例如,在 Web 应用程序中,我们可能想知道该用户一年中每天的页面浏览量。
|
|
扩展:
- INCR 与 EXPIRE 限制计数器统计时间窗口
SET key value !GET
以原子方式获取当前计数器值并将其重置为零- 使用其他原子递增/递减命令,例如DECR或INCRBY可以根据用户执行的操作处理可能变大或变小的值。例如,想象一下在线游戏中不同用户的得分。
限流 Rate limiter
速率限制器模式是一种特殊的计数器,用于限制可以执行操作的速率。这种模式的经典实现涉及限制可以针对公共 API 执行的请求数量。
我们提供了这种模式的两种实现INCR,我们假设要解决的问题是将 API 调用的数量限制为 每个 IP 地址每秒最多 10 个请求。
|
|
BitMap 使用场景
bitmap 不是一种实际的数据类型,而是在字符串类型上定义的一组面向位的操作。
因为 Redis 的字符串是二进制安全的,所以位图被简单地编码为字节流。字符串的第一个字节对应于位图的偏移量 0..7,第二个字节对应于 8..15
offset 参数范围 [0, 2^23) (最大512M bitmaps)
|
|
签到
根据日期 offset = (今天是一年中的第几天) % (今年的天数),key = 年份:用户id。
|
|
统计活跃用户
日期作 key 用户id 作 offset, 当日活跃设置为1.
|
|
用户是否在线
只需要一个key,然后用户id 为 offset, 如果在线1,不在线设置0
布隆过滤器
消息队列
List提供了两个阻塞的弹出操作:blpop/brpop,可以设置超时时间
- blpop:blpop key1 timeout 移除并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
- brpop:brpop key1 timeout 移除并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
上面的操作。其实就是java的阻塞队列。学习的东西越多。学习成本越低
- 队列:先进先除:rpush blpop,左头右尾,右边进入队列,左边出队列
- 栈:先进后出:rpush brpop
点赞、签到、打卡
假如上面的微博ID是t1001,用户ID是u3001
用 like:t1001 来维护 t1001 这条微博的所有点赞用户
- 点赞了这条微博:sadd like:t1001 u3001
- 取消点赞:srem like:t1001 u3001
- 是否点赞:sismember like:t1001 u3001
- 点赞的所有用户:smembers like:t1001
- 点赞数:scard like:t1001
- 是不是比数据库简单多了。
标签
|
|
关注、推荐模型
follow 关注 fans 粉丝
|
|
目前存在的问题是,我的关注列表 & 我的粉丝列表,无法做到按关注时间排序,终端下显示是结果按ID正序排列的。 考虑的解决方案是添加关注时同时存一份有序集合,关注时的时间戳是score。
ZADD 1:follow 1457871625 2
ZADD 2:fans 1457871625 1
那么我的关注列表是:
ZREVRANGE 1:follow 0 -1
同时,ZREVRANGE查询时的索引可以作为分页游标,基本解决目前的问题。
粉丝列表同理。
排行榜
id 为6001 的新闻点击数加1:
zincrby hotNews:20190926 1 n6001
获取今天点击最多的15条:
zrevrange hotNews:20190926 0 15 withscores