服务端缓存与浏览器缓存的边界
判断规则:用户私有内容(笔记、剪藏正文)缓存在浏览器侧,不复制进服务端缓存;服务端 Redis 保留给队列、限流这类与用户内容无关的职责。不要因为「项目里已经有 Redis」就把 API 响应也塞进去。
| Redis | IndexedDB | |
|---|---|---|
| 位置 | 服务端,应用与数据库之间 | 浏览器,页面与网络之间 |
| 共享范围 | 跨请求、跨用户(进程外) | 单浏览器、单用户 |
| 生命周期 | 服务端 TTL / 淘汰策略控制 | 跨会话存活,换设备即失效 |
| 典型用途 | 队列、限流、会话、共享缓存 | 离线数据、本地草稿、会话级内容缓存 |
三条推论:
- 缓存的目的是「少一次远端往返」时,两层都能做,但先问数据是不是用户私有。 私有正文进服务端缓存 = 把同一份私有数据再多复制一处,暴露面变大,而收益只在「多用户命中同一 key」时才成立 —— 个人知识库场景不成立。
- 「已经有 Redis」不等于「该用它做内容缓存」。 队列是进程内必需的基础设施,内容缓存是可选的优化,两者共用一套 Redis 不冲突,但职责要分开声明。
- 切栏目卡顿的修法不是「让列表接口带回全文」。 正确姿势是浏览器侧会话级缓存 + 请求去重 + 后台静默刷新:先拿缓存立即渲染,再在后台刷新,而不是把大字段塞回列表响应。
本日实例(mewmo):Web 端已同时使用远端 Upstash Redis 与远端 Neon,但 Redis 只服务 BullMQ,没有缓存笔记 / 剪藏的 API 响应,所以每次切栏目仍然访问远端数据库。方案定为浏览器会话级缓存 + 后台刷新,而不是把全文放进服务端缓存。
相关
- 实时与异步 —— 队列与缓存常在同一套 Redis 上,但属于不同的时序模型
- 缓存命中率 —— 服务端缓存的收益要用命中率衡量,浏览器缓存则看「是否省下这次请求」
- 数据权威模型要先于同步与迁移确定 —— 「哪一层持有数据」和「哪一层持有缓存」是同一个模型问题的两面
- 知识库先编译再查而不是查询时拼原文 —— 同属「在什么时刻、哪一层把数据整理好」的取舍
- 列表切换要用master-detail而非重建列表 —— 浏览器侧缓存是为了让列表不被重建时仍能立即显示
- 离线存储的三个等级 —— 从会话缓存到完整离线编辑的三个档位
- 页面切换的四种刷新要分清 —— 先定位慢在哪一条链路,再决定用哪层缓存
- 后台任务队列选型 —— Redis 去掉队列职责后,剩下的边界在哪