noeviction是redis默认的保守内存策略:内存达maxmemory后硬性拒绝所有写命令(如set、hset),返回oom错误,不淘汰key、不等待、不降级,仅允许读操作,导致“能读不能写”;其本质是显式暴露容量风险,而非故障。

noeviction 不是“有问题”,而是把问题显式暴露出来——业务写入直接失败,不是延迟升高或数据丢失,但很多团队没准备好接住这个错误。
为什么 noeviction 会让业务突然报错
它不淘汰、不等待、不降级,只在 used_memory 超过 maxmemory 后,对所有写命令(SET、HSET、LPUSH、INCR)返回固定错误:(error) OOM command not allowed when used memory > 'maxmemory'。注意:DEL 和所有读命令(GET、HGETALL)照常执行——所以你可能看到“能查不能存”的割裂现象。
常见误判点:
- 以为“还有 5% 内存余量”就安全,却忽略了
client-output-buffer或slave_buf已悄悄吃掉 200MB(尤其主从同步卡顿或客户端堆积响应时) - 监控只看
used_memory_human,没盯mem_fragmentation_ratio:若该值 > 1.5,说明 RSS 占用远超逻辑内存,真实可分配空间早已见底 - 误以为
evicted_keys为 0 就没风险——但noeviction下这个指标永远为 0,它根本不淘汰,所以不能当健康信号用
哪些业务路径最扛不住 noeviction
不是所有写操作都一样脆弱。以下场景一旦触发 OOM 错误,极易引发连锁故障:
- 用户登录态写入:
SET session:abc123 "{'uid':1001,'role':'admin'}" EX 1800失败 → 登录接口返回 500,前端反复重试加剧压力 - 订单状态更新:
HSET order:20260526001 status "paid" updated_at "2026-05-26T12:15:00"拒绝 → 支付成功但状态未落库,财务对账断点 - 计数器累加:
INCR user:1001:login_count失败 → 用户行为漏统计,风控规则失效 - 消息队列桥接写入(如 Redis Stream):
XADD stream:pay_events * event "timeout" order_id "20260526001"拒绝 → 事件丢失,下游无法补偿
关键区别在于:这些操作通常无重试兜底、无幂等保护、不检查返回值,错误直接透出到上游 HTTP 响应或日志。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
排查时最容易漏掉的三个隐性内存黑洞
used_memory 没超限 ≠ 内存够用。Redis 的真实可用内存还被三类“隐身”占用挤压:
-
client-output-buffer:特别是 pub/sub 客户端消费慢、或从节点网络抖动时,缓冲区会持续膨胀,配置项是client-output-buffer-limit pubsub和client-output-buffer-limit slave -
lua_scripts缓存:每个 EVAL 脚本会被缓存,大量动态脚本(如带时间戳的 key 名拼接)会导致lua_script_cache_bytes持续增长 - bigkey 的 lazy-free 开销:删除一个 10MB 的
hash,Redis 默认异步释放,但内存不会立刻归还,used_memory_peak_human可能比当前used_memory_human高出数倍,而mem_fragmentation_ratio会同步飙升
验证方法:redis-cli memory doctor 会直接指出这三类问题是否存在,比手动 grep 更快。
noeviction 真正的高危时刻:告警和扩容没闭环
它本身不危险,危险的是配套机制缺失。比如:
- 监控只设了
used_memory > 95%告警,但没关联mem_fragmentation_ratio趋势图,导致误判容量余量 - 扩容流程依赖人工介入,而值班人员收到告警时,
mem_oom_events已累计 17 次,业务写入中断超 4 分钟 - 客户端没捕获
(error) OOM command not allowed...,而是当成网络超时重试,进一步压垮连接池
金融、支付、核心账户类系统必须把 noeviction 当作“熔断开关”来设计:错误码要结构化(如 ERR_MEMORY_FULL),上游必须有降级路径(如切本地缓存、记录本地日志异步重试),扩容动作需自动化触发且带回滚检测。










