秒杀场景必须用allkeys-lfu,因其基于带衰减的访问频次淘汰,能守住预热后的爆款key;allkeys-lru依赖最近访问时间,易致冷数据误续命、爆款反复加载,引发缓存雪崩。

秒杀大促期间必须用 allkeys-lfu,其他策略在高并发突发访问下都容易引发缓存雪崩。
为什么 allkeys-lru 在秒杀开始前就让 Redis 内存爆掉
不是 QPS 太高,是冷数据批量加载撞上错误淘汰逻辑。用户一刷商品页,product:1001、sku:2005:stock、countdown:1001 这类 key 集中回源加载;但 allkeys-lru 只看“最后一次访问时间”,刚加载进来的爆款 key 时间戳最新,反而立刻被踢——而一批后台扫描的冷 key(比如每小时跑一次的 user:*:profile)因“刚被扫过”被误续命。
结果就是:下一轮请求又打穿缓存查库 → 再加载 → 再被淘汰 → 内存持续涨 → OOM。这种“加载→淘汰→再加载”循环,在预热不充分时几乎必然发生。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
maxmemory-samples默认为 5,采样偏差大,冷 key 被偶然选中续命的概率不可忽视 -
allkeys-lru对单次突发访问零抵抗力,完全不适合秒杀这种“短时高频集中读”的场景 - 即使调高
maxmemory-samples到 10 或 20,也只改善近似精度,无法改变 LRU 本质缺陷
allkeys-lfu 是怎么守住爆款 key 的
allkeys-lfu 的 lru 字段低 16 位存频次(带衰减),高 8 位存时间戳。爆款 key(如 sku:2005:stock)在预热后被高频读取,频次快速上升;而冷 key 即使被扫一次,频次也会随衰减机制迅速回落,权重自然偏低。
- 预热后的核心 key 几乎不会被淘汰——只要访问频次稳居前列
- 后台定时任务(如统计类)不会污染缓存,冷 key 衰减后自动让位
- 它不依赖 TTL 控制生命周期,适合那些本就不该设过期时间的核心状态(如实时库存)
- 频次是 8 位无符号整数,最大值 255;秒杀期间每秒访问超百次的 key 会饱和,但这反而是好事:说明它确实是绝对热点,本就不该被淘汰
其他策略为什么不能用
volatile-lru 和 volatile-ttl 要求 key 必须设过期时间,但秒杀库存这类强一致性状态通常不能加 TTL——否则可能造成超卖;noeviction 直接拒绝写入,订单直接失败;allkeys-random 完全无区分度,等于把淘汰权交给运气;volatile-lfu 虽然也是 LFU,但只作用于带过期时间的 key,覆盖范围太窄,无法保护未设 TTL 的核心状态。
- 用
volatile-*系列的前提是:你愿意给所有参与淘汰的 key 统一加 TTL,且能接受其带来的语义风险(比如库存 key 过期导致误判) -
allkeys-random在缓存命中率敏感的业务里基本等同于放弃缓存价值 - Redis 4.0+ 才支持 LFU,确认版本用
redis-server --version,低于 4.0 的实例必须升级
真正容易被忽略的是:淘汰策略只是防线之一,它救不了没预热的 key,也压不住没限流的请求。如果你发现 allkeys-lfu 下仍有大量 miss,问题大概率不在策略本身,而在预热覆盖度或前端聚合查询的设计上。










