noeviction在生产环境基本不可用,因其内存满时直接拒绝所有写入并返回oom错误,导致依赖缓存写的业务(如会话更新、计数器)立即中断;仅适用于完全不允许数据丢失且具备实时告警+人工扩容能力的离线分析类实例。

直接结论:高并发场景下,allkeys-lru 是最稳妥的默认选择,但必须配合 maxmemory 显式设置和 maxmemory-samples 调优;若业务存在明显冷热分层(如商品详情 vs 秒杀库存),allkeys-lfu 更合适。
为什么不能用默认的 noeviction?
默认策略 noeviction 在内存满时直接拒绝写入,返回 (error) OOM command not allowed when used memory > 'maxmemory'.。高并发下大量写失败会引发雪崩——比如订单创建、库存扣减、用户登录态更新全部被拒,错误率瞬间飙升。这不是“优雅降级”,是服务中断。
- 它只适合极少数场景:Redis 仅作纯读缓存 + 有外部强校验 + 写操作完全绕过 Redis
- 生产环境几乎从不使用,除非你明确接受“写失败即告警人工介入”
- 哪怕只是临时扩容,也要先切到
allkeys-lru或volatile-lru,再改maxmemory
allkeys-lru 和 allkeys-lfu 怎么选?
两者都作用于全部 key,区别在于淘汰依据:lru 看“最后一次访问时间”,lfu 看“总访问频次”。高并发下选错会导致热点数据被误删。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
allkeys-lru:适合访问时间局部性强的场景,比如用户 session、临时 token、短时效商品列表。新写入的 key 如果长期没被读,很快被淘汰 -
allkeys-lfu:适合访问频次差异大的场景,比如首页 Banner(每秒千次读)vs 后台配置项(每天读一次)。LFU 会保留高频 key,即使它最近没被访问 - 注意:
lfu的计数器有衰减机制,默认 1 分钟衰减一次。如果 key 访问间隔大于衰减周期,计数归零 → 可能被误判为冷数据。可通过lfu-log-factor和lfu-decay-time调整
高并发下必须调优的两个参数
Redis 的 LRU/LFU 都是近似算法,靠采样实现。默认采样数 maxmemory-samples 是 5,对高并发大容量实例远远不够 —— 容易漏掉真实冷 key,导致缓存命中率断崖下跌。
-
maxmemory-samples:建议设为 10~20。值越大,淘汰越精准,但 CPU 开销略增;超过 30 收益递减明显 -
maxmemory:必须显式设置!不能依赖系统内存自动增长。推荐设为物理内存的 75%~85%,留出空间给 Redis 自身开销(如复制缓冲区、AOF rewrite) - 别用
config set maxmemory 0清空限制 —— 这等于关闭淘汰,等同于noeviction,只是不报错,更危险
volatile-* 策略在高并发里容易踩坑
volatile-lru、volatile-ttl 这类策略只淘汰带 EXPIRE 的 key。问题在于:高并发写入时,如果大量 key 没设过期时间(比如用户 session 用 PERSIST 保留),它们永远不参与淘汰 → 内存持续上涨直至 OOM。
- 除非你 100% 确保所有可淘汰数据都设置了 TTL,否则不要用
volatile-*类策略 - 常见误用:把用户登录态存为永不过期 key,又配了
volatile-lru→ 登录态占满内存,真正该淘汰的缓存反而动不了 - 如果必须混合持久化数据(如配置中心)和缓存数据,正确做法是:用不同 DB(
SELECT 0存配置,SELECT 1存缓存),各自配独立maxmemory和策略
真正关键的不是策略名字本身,而是你是否清楚每个 key 的生命周期和访问模式。线上跑着 20 个业务模块的 Redis 实例,光靠一个全局 allkeys-lru 往往不够 —— 更可靠的做法是按业务域拆实例,或用 Redis 6+ 的 ACL + 多 DB 隔离,再配策略。










