结论是命中率提升取决于策略与业务访问模式的匹配度;必须先配置maxmemory,否则淘汰策略不会触发,即使设为allkeys-lfu也无效;volatile-*类策略存在可淘汰键不足导致OOM的风险;allkeys-lru适用于时间局部性强的场景,allkeys-lfu适用于访问频次差异大的热点场景。

直接说结论:命中率提升不靠“选对策略”本身,而靠策略与业务访问模式的匹配度。选错策略时,allkeys-lru可能比volatile-lfu更低效;选对了但没设maxmemory,策略根本不会触发。
必须先配maxmemory,否则淘汰策略形同虚设
Redis 默认不限制内存使用,maxmemory-policy只在内存超限时生效。不设这个值,哪怕配置了allkeys-lfu,也永远不会淘汰任何 key。
- 配置方式优先用字节单位(避免单位歧义):
maxmemory 2147483648(2GB),而不是maxmemory 2gb - 运行时动态设置要带单位:
CONFIG SET maxmemory 2gb,但生产环境建议写死在redis.conf中 - 如果应用部署在容器里,还要确认容器内存 limit ≥ Redis 的
maxmemory,否则 OOM Killer 会先干掉进程
allkeys-lru和allkeys-lfu不是互换关系,适用场景截然不同
LRU 假设“最近访问过的更可能再被访问”,LFU 假设“访问频次高的更可能再被访问”。两者在真实流量下表现差异很大。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 适合
allkeys-lru:用户会话、商品详情页缓存(访问有时间局部性,刚看过的商品很可能马上加购) - 适合
allkeys-lfu:热搜榜单、首页推荐位(少数 key 被反复读取,其他 key 访问一次就沉底) - 注意 LFU 的衰减机制:Redis 会定期对计数器做衰减(默认每分钟一次),避免历史高频数据长期霸占内存;可通过
lfu-log-factor和lfu-decay-time调参,但多数场景保持默认即可
别忽略volatile-*类策略的隐性风险
这类策略只在设置了过期时间的 key 中筛选淘汰目标。表面看“保护永久数据”,实际容易导致内存无法释放。
- 现象:内存持续上涨至
maxmemory,但volatile-lru找不到足够候选 key 可淘汰,最终写操作报(error) OOM command not allowed - 原因:大量 key 没设 TTL(比如用户基础信息用
SET直接写入),或 TTL 设置过长(如EXPIRE user:1001 86400),导致“可淘汰池”太小 - 对策:要么统一给所有缓存 key 加 TTL(哪怕随机±300s),要么改用
allkeys-*策略并接受部分永久 key 被淘汰
淘汰不是零成本,大流量下要注意阻塞延迟
Redis 是单线程执行淘汰逻辑的。当一次写入触发淘汰,且需扫描+删除大量 key 时,当前请求会被阻塞,表现为 P99 延迟突增。
- 避免单次写入引发大规模淘汰:控制单个
LPUSH/HSET的数据量,尤其避免批量导入未预估内存占用 - 监控指标重点关注:
evicted_keys(已淘汰 key 总数)、expired_keys(因 TTL 过期删除数),两者差值过大说明淘汰策略正在高频介入 -
allkeys-random虽快但不可控,仅适合压测或临时应急;生产缓存绝不推荐
真正卡点不在策略名怎么念,而在你是否清楚自己缓存里哪些 key 是“热”的、哪些是“长尾”的、哪些压根不该进 Redis —— 淘汰策略只是最后一道防线,不是兜底方案。

















