redis缓存淘汰策略不处理写请求,仅在内存达限时影响读操作或写前检查;写密集场景推荐allkeys-lfu,配合限流、写合并、异步降级等分层防护措施。

Redis缓存淘汰策略本身不处理写请求
这是最容易误解的一点:maxmemory-policy 只在内存达到 maxmemory 限制后,对「读操作触发的键查找」或「写操作前的内存检查」阶段起作用,它不会缓冲、排队、限流或重试写请求。高并发写压过来,Redis 依然会逐条执行 SET、HSET 等命令——除非 OOM 被系统 kill 或触发了写阻塞。
真正需要搭配使用的机制是:
- 客户端侧做写合并(如将多条
user:1001:profile更新攒成一次HSET) - 服务端加限流(如用令牌桶控制每秒最多 500 次写)
- 用
PIPELINE减少网络往返,但不减少 Redis 单线程负载 - 把非关键写降级为异步(如发到 Kafka,再由消费者批量写 Redis)
哪些淘汰策略适合写密集型场景
写多读少时,频繁写入新 key 会导致内存快速打满,此时淘汰策略的选择直接影响命中率和抖动程度:
-
allkeys-lru:最常用,但注意它会驱逐任意 key,包括刚写入但还没来得及读的热 key -
volatile-lru:只淘汰带过期时间的 key,适合你主动给所有写入 key 加EX的场景(例如 session、临时 token) -
allkeys-lfu:比 LRU 更适合写多读少——它按访问频次淘汰,刚写入但零访问的 key 会被优先踢出 - 避免用
noeviction:写满直接报(error) OOM command not allowed when used memory > 'maxmemory'
实测中,allkeys-lfu 在用户行为日志类写入(key 随机、value 小、读极少)下,内存利用率比 LRU 高 20%–30%。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
写请求引发的隐性淘汰风险
你以为只是 SET 一个 key,但背后可能触发连锁淘汰:
- 执行
SET user:1001:name "Alice" EX 3600时,如果内存已超限,Redis 先按策略删一个 key,再存新 key——这个过程是同步的,会增加单次写延迟 - 用
APPEND或INCR扩展已有 value,也可能因扩容导致内存超限,触发淘汰 - 集群模式下,某个 slot 内存独占超标(比如某用户 key 特别多),该节点更容易触发本地淘汰,造成不均衡
可通过 INFO memory | grep -E "(used_memory|maxmemory|mem_allocator)" 实时观察,配合 MEMORY USAGE <key></key> 定位大 key。
更务实的写保护组合方案
单纯调淘汰策略解决不了写洪峰。生产环境常见做法是分层控制:
- 接入层 Nginx / API 网关:用
limit_req限制每 IP 每秒写请求数 - 应用层加本地缓存(Caffeine)+ 延迟双删:先更新 DB,休眠 100ms,再删 Redis key,避免写穿透
- Redis 配置上设
maxmemory 4gb+maxmemory-policy allkeys-lfu+maxmemory-samples 10(提高 LFU 采样精度) - 监控
evicted_keys和expired_keys指标突增,作为写流量异常的信号
淘汰不是银弹,它只是内存守门员;真正的写压力,得靠前置削峰和数据模型优化来扛。比如把 100 个字段拆成 10 个 hash,比 100 个独立 string key 更抗写。










