热点数据防击穿不应依赖redis持久化,而应采用永不过期+异步刷新、互斥锁重建或本地缓存兜底。rdb/aof仅解决重启丢数,不缓解运行时并发穿透;有效方案是set无ttl+定时刷新、nx锁内重建并动态续期、或用本地缓存拦截请求。

热点数据本身不该靠 Redis 持久化来扛击穿——持久化解决的是 Redis 重启后数据丢失问题,不是并发重建压力问题。真正要做的,是让热点数据“不依赖过期机制”,或“失效时只允许一个线程重建”。
Redis 持久化(RDB/AOF)对缓存击穿无效
很多人误以为开启 RDB 或 AOF 就能缓解击穿,其实完全无关:
-
RDB是定时快照,AOF是命令日志,两者都只在 Redis 重启时恢复数据,不影响运行时 key 过期行为 - 击穿发生在 key 刚过期、大量请求并发穿透的瞬间,此时数据还在内存里(只是标记为 expired),持久化文件根本没参与这个流程
- 即使开了
appendonly yes,也挡不住GET product:1001返回 nil 后那几千个 goroutine 同时调db.Query
真正有效的“持久化级”应对:永不过期 + 异步刷新
所谓“热点数据持久化”,实际是指让它长期稳定存在于缓存中,不因 TTL 到期而中断服务。这不是靠磁盘文件,而是靠业务逻辑控制:
- 写入时不用
SETEX,改用SET product:1001 "data"(不带过期时间) - 用独立后台任务(如
time.Ticker或 Quartz)定期执行GET product:1001 → 查询 DB → SET product:1001 new_data - 刷新间隔必须短于业务可容忍的数据陈旧窗口,比如商品价格每 30 秒刷一次,比设 5 分钟 TTL 更安全
- 注意:需配合版本号或时间戳字段,避免脏写覆盖;刷新失败时保留旧值,不主动删 key
互斥锁重建时,别把锁和持久化混为一谈
用 SET product:1001 "data" NX EX 60 加锁重建,常被误认为“带持久化”,其实:
-
NX保证只有一个线程进 DB,EX 60只是防死锁,不是为了“持久” - 60 秒后依然会过期,下一轮并发照样击穿——这方案本质是“限流重建”,不是“持久化”
- 若真想延长保护,得动态续期:重建成功后立刻
EXPIRE product:1001 300,且在锁内完成 - Redis 集群下
SETNX要用Redlock或 Lua 原子脚本,否则分片间锁失效
最容易被忽略的一点:本地缓存(如 freecache 或 bigcache)加一层,比什么都管用。它不依赖 Redis 持久化,却能在 Redis 击穿瞬间兜底——只要应用进程没重启,一级缓存里的热点数据就还在。











