客户端缓存
Node-Redis 新版支持 Redis Client-Side Caching:客户端在 Node.js 进程内保存读取结果,Redis 服务端在相关键变化时发送失效通知。
请求路径可能从:
Node.js -> 网络 -> Redis
进一步缩短为:
Node.js -> 进程内缓存
基本配置
该能力需要 RESP3:
const client = createClient({
RESP: 3,
clientSideCache: {
ttl: 30_000,
maxEntries: 10_000,
evictPolicy: "LRU",
},
});
配置含义:
ttl:本地缓存项存活时间,单位以安装版本文档为准;官方示例中0表示不因时间过期。maxEntries:最多缓存多少项;0表示不限数量。evictPolicy:达到上限后的淘汰策略,支持LRU或FIFO。
初学者不应使用“无限 TTL + 无限条目”的组合,因为每个 Node.js 进程都可能持续占用更多内存。
它与普通 Redis 缓存有什么区别
普通 Cache-Aside:
- 数据保存在 Redis。
- 所有应用实例共享。
- 每次命中仍有网络请求。
Client-Side Caching:
- 数据还会缓存在每个 Node.js 进程内。
- 命中时不访问网络。
- 每个进程都有自己的内存占用。
- 依赖 Redis 的失效通知维持一致性。
它是 Redis 缓存之上的二级缓存,而不是替代 Redis。
何时值得使用
- 同一小批键被单个进程高频重复读取。
- 网络延迟已经成为可测量的性能瓶颈。
- 数据允许极短时间的陈旧。
- 团队能监控每个 Node.js 实例的内存。
不建议一开始就启用。先使用普通 Node-Redis 缓存并测量延迟,再决定是否需要。
失效事件
启用相关 tracking 配置时,客户端可监听 invalidate 事件。事件中的键可能是字符串、Buffer 或 null,具体取决于配置和通知语义。
不要把失效事件当成可靠业务消息。它用于缓存一致性,不保证具备队列的持久化、确认和重试能力。
多进程注意事项
如果使用 Node.js Cluster、PM2 或容器扩容,每个进程都有独立本地缓存:
Redis
├─ API 实例 A 的本地缓存
├─ API 实例 B 的本地缓存
└─ API 实例 C 的本地缓存
容量规划要乘以实例数量。例如每个实例允许 100 MB,20 个实例总计可能使用 2 GB 应用内存。
最佳实践
- 设置有限
maxEntries。 - 通常仍设置有限 TTL,作为失效通知之外的第二层保护。
- 先压测普通 Redis,再压测客户端缓存,比较命中率、延迟和内存。
- 不把巨大对象放入本地缓存。
- 升级 Node-Redis 前检查 Client-Side Caching 的版本说明。