Redis

洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法
帅旋
关注
充电
IT宅站长,技术博主,共享单车手,全网id:arthinking。

Redis应用之ZSET:评论分页

发布于 2021-06-16 | 更新于 2024-03-03

我们在给具有分页的评论列表添加缓存的时候,由于新的评论一直在入库,所以分页的界限也会在变化。如果按照以下得到的分页结果进行缓存:

1
select * from t_user order by id desc limit 10 offset 15;

那么,每当有新的记录插入表的时候,所有分页内容都将产生变化,导致所有分页缓存都会失效。

如何避免大量分页缓存失效?

如果是写评率比较少的场景,那么我们可以把读取评率比较高的前几页内容给缓存起来,每次只触发更新这几页缓存即可。

但是如果写的很频繁,那么就需要频繁的更新这几页的内容了,会导致写操作变重。或者业务需要,前几十页的访问评论都是比较高的场景,有什么比较好的缓存方法呢?

这个时候我们就可以使用Redis中的有序集合来实现分页缓存了:

  • 我们可以给每个评论设置一个权重值,可以是当前时间戳,通过ZADD添加到ZSET中;
  • 然后通过 ZRANGEBYSCORE 按照score进行分页查找

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count][1]

Available since 1.0.5.

时间复杂度:O(log(N)+ M),其中N是排序集中的元素数,M是要返回的元素数。如果M为常数(例如,始终要求使用LIMIT限制前10个元素),则可以将其视为O(log(N))。

以下是具体的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 按照评论时间微秒设置每条评论的score
127.0.0.1:6379> ZADD comments 1621900305499398 '沙发'
127.0.0.1:6379> ZADD comments 1621900588459950 '板凳'
127.0.0.1:6379> ZADD comments 1621900628104233 '牛逼'
127.0.0.1:6379> ZADD comments 1621900661283904 'itzhai.com'

# 按照score排序进行范围查找,实现分页效果,查找第一页
127.0.0.1:6379> zrangebyscore comments 0 1621901132532229 withscores limit 0 3
沙发
1621900305499398
板凳
1621900588459950
牛逼
1621900628104233

# 查找第二页,使用上一页返回的最后一个微秒时间戳作为查找的min参数
127.0.0.1:6379> zrangebyscore comments (1621900628104233 1621901132532229 withscores limit 0 3
itzhai.com
1621900661283904

image-20211010135748319

另外,对于更新非常频繁需要排序的列表,都可以考虑使用ZSET。

References


  1. ZRANGEBYSCORE. Retrieved from https://redis.io/commands/ZRANGEBYSCORE ↩︎

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/redis/zset-application.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。