redis 5.x 不支持客户端缓存机制,更无法用于防击穿;6.x 通过 client tracking 提供失效通知能力,6.2+ 结合 client caching yes 才实现完整防击穿闭环。

Redis 5.x 真的不支持客户端缓存防击穿吗?
不是“不支持”,而是压根没提供客户端缓存(client-side caching)机制,更谈不上用它防击穿。Redis 5.x 的 GET、SET 等命令完全无感知客户端本地状态,服务端不会跟踪、校验或失效客户端缓存——所以所谓“防击穿”在 5.x 里是应用层自己硬扛,比如靠布隆过滤器+空值缓存+互斥锁组合实现。
Redis 6.x 的 CLIENT TRACKING 是怎么介入防击穿的?
它本身不直接防击穿,但提供了关键基础设施:服务端能主动推送 key 失效通知(invalidation messages),让客户端及时清理本地副本。这使得「本地缓存 + 远程兜底」架构真正可控。启用方式很简单:
CLIENT TRACKING ON REDIRECT 5
其中 REDIRECT 5 表示把失效消息发给 ID 为 5 的客户端(通常是代理或客户端库内部维护的监听连接)。常见配合模式包括:
- 应用用
GET读取后,同时在本地内存缓存结果,并标记该 key 受服务端追踪 - 当其他客户端执行
DEL、SET、FLUSHDB等影响该 key 的操作时,Redis 自动向所有追踪它的客户端发送invalidate消息 - 客户端收到后立刻删掉本地对应缓存项,下次请求就会穿透到 Redis,避免脏读或陈旧空值
为什么光有 CLIENT TRACKING 还不够?关键补丁在哪儿?
因为击穿本质是「缓存未命中 + 高并发查 DB」,而 CLIENT TRACKING 只解决「缓存一致性」,不解决「并发穿透」。Redis 6.2+ 引入的 CLIENT CACHING YES(配合 GET 命令)才真正补上一环:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 客户端在发
GET前加CLIENT CACHING YES,表示“这次响应允许被本地缓存” - Redis 在返回值时附带隐式 TTL 和 key 元信息,客户端库可据此自动设本地过期时间
- 若此时 key 被删除,服务端推送
invalidate,客户端立即清除——整个链路闭环了 - 注意:
CLIENT CACHING必须和CLIENT TRACKING ON同时启用,否则无效
没有这个协同,客户端即使收到 invalidate,也不知道该清哪个 key,或者干脆没缓存过那个 key。
实际部署最容易踩的三个坑
很多团队开了 CLIENT TRACKING 却发现没生效,问题往往不在协议本身:
- 客户端连接必须保持活跃且支持 RESP3 —— Jedis 4.x / Lettuce 6.1+ 才完整支持,老版本连
REDIRECT参数都解析不了 - 防火墙或代理(如 Twemproxy、Codis)会吞掉 PUSH 类型的 RESP3 消息,导致 invalidate 不达;必须直连 Redis 或确认中间件透传
PUSHframe -
tracking-table-max-keys默认是 100 万,但单个客户端追踪 key 数超限后静默失败,日志也不报错;建议监控instantaneous_ops_per_sec和tracking_total_keys指标
真正难的从来不是开开关,而是让整个链路里的每一段——从客户端序列化逻辑、网络栈、Redis 配置、到业务缓存策略——对齐同一个失效语义。漏掉任意一环,“防击穿”就退化成“多了一层可能出错的缓存”。










