redis--018

、传统分页为什么在 Feed 流会出问题

传统分页:page页码 + size页大小,依靠数组下标偏移取数据。

Feed 流会不断插入新数据(别人发新笔记),列表整体顺序、下标会发生变动。

举例: t1:第一页读到 10、9、8、7、6(5 条) t2:中间插入一条新数据 11,所有旧数据下标全部后移一位 t3:再查第 2 页,按传统 page=2、size=5,会读到 6、5、4、3、2 ✘ 问题:6 这条数据重复读取,出现重复条目。 新消息插入会打乱下标,传统偏移分页不再可靠。

二、滚动分页(游标分页 /lastId 方案)

核心思路:不使用页码,记录上一页最后一条的标识(这里是时间戳 score,叫 max/lastId),下一页从这个位置往后查

  1. 第 1 页:lastId = ∞(从最新时间开始),取 size 条,记录这一页最小的时间戳作为游标
  2. 中间有新数据插入,新数据只会排在最上面,不会干扰旧游标
  3. 第 2 页:直接传入上一页拿到的lastId,只查询小于该时间戳的数据,不会读到已经加载过的旧内容,不会重复

图中例子: 第一页拿到 10‑6,记下 lastId=6; 之后新增 11,排在最顶部; 加载下一页从 lastId=6 向后取,拿到 5‑1,数据不重复。

三、Redis 选型:SortedSet(ZSet)

业务:博主发笔记,推送到每一个粉丝的收件箱

  • Key:feed:用户id,每个粉丝一个独立 zset 收件箱
  • member:blog 笔记 id
  • score:发布时间戳,天然按时间排序,新消息 score 更大排在前面

✅ ZSet 优势:

  1. score 时间戳自动完成时间排序;
  2. 支持ZREVRANGEBYSCORE逆序按 score 范围查询,完美适配滚动游标分页;
  3. 可以拿到每条数据对应的 score(时间戳),作为下一页的游标参数。

❌ List 为什么不行: List 按下标读取,新数据 LPUSH 插入头部,旧元素下标全部变化,和传统分页一样出现重复 / 漏数据。

四、完整业务流程(探店笔记 Feed 推送)

1)新增笔记(写流程,推模式)

  1. 把 blog 笔记存入 MySQL 数据库
  2. 查询该博主的所有粉丝
  3. 遍历每一位粉丝,向粉丝个人的 ZSet 收件箱,添加这条 blogId,score = 当前时间戳

⚠️推模式缺点:博主粉丝极多的时候,循环推送压力大;优化可以改成拉模式(用户刷的时候自己去查关注列表)

2)查询 Feed 收件箱(读流程,滚动分页)

前端传两个参数:

  • max:上一页最后一条笔记的时间戳(游标,第一页传无穷大)
  • offset:偏移补偿(相同时间戳多条数据,用来跳过已经读过的条目)

后端逻辑:

  1. 根据当前登录用户拿到他的 feed 收件箱 key
  2. ZSet 逆序查询:score ≤ max,limit 偏移量、size 条
  3. 返回笔记 id 列表,同时返回本页最小的时间戳作为新 max、本页相同时间戳的数量作为 offset,传给前端作为下一次请求参数
  4. 根据 blogId 批量去 MySQL 查笔记完整内容返回给前端
相关推荐
两锭子2 小时前
Redis基础
redis
烟沙九洲2 小时前
Redis 缓存穿透、缓存击穿、缓存雪崩
数据库·redis
字节探索2 小时前
Redis 只会当缓存用?这 10 大实战场景,让你的系统快到飞起
redis·后端
于樱花森上飞舞3 小时前
【Redis】哨兵详解
java·开发语言·数据库·redis
Rain的Java大神之路14 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog15 小时前
Java 接入Redis: 通用命令与键管理
java·服务器·redis
Wang's Blog15 小时前
Java 接入Redis: 列表集合与有序集合操作命令
java·服务器·redis
行百里er1 天前
5 分钟跑起 Redis(Docker 版)
redis·后端·docker
福大大架构师每日一题1 天前
redis 8.10.2发布:安全修复集中落地,事务 ACL、集群总线与模块稳定性全面加固
redis