根本原因是写入未控内存增长节奏且过期策略失当;须统一用allkeys-lru/lfu、显式设TTL、写入前检查内存,禁用逐条SET,改用MSET或PIPELINE,调大maxmemory-samples,敏感业务加时间戳校验。

为什么大批量写入会瞬间触发淘汰?
根本原因不是“写得多”,而是写入时没控制内存增长节奏,加上过期策略和键生命周期管理失当。比如用 SET 逐条写入万级数据、不设 EXPIRE、又用了 volatile-lru 策略——那些没设置过期时间的键完全不参与淘汰,内存只增不减,很快触达 maxmemory 阈值,Redis 就开始疯狂踢键。
批量写入前必须做的三件事
这不是“优化建议”,是防止服务抖动的底线操作:
- 统一启用
allkeys-lru或allkeys-lfu策略(别用volatile-*),确保所有键都纳入淘汰范围,避免“漏网之键”吃光内存 - 所有缓存键必须显式设置 TTL,哪怕只是
300秒;Dify、Spring Boot 等框架中常因MSET批量写入遗漏 TTL,要用 Lua 脚本兜底:for i = 1, #KEYS do redis.call('SET', KEYS[i], ARGV[i]) redis.call('EXPIRE', KEYS[i], 300) end - 写入前先用
INFO memory查当前used_memory_human和mem_fragmentation_ratio,若已超 75%maxmemory,就暂停写入或切流降级
批量写入时该用什么命令?
别用循环调 SET,那是给 Redis 下慢性毒药。每轮 SET 都是一次 RTT + 单线程串行执行,万级写入等于把其他请求全堵死。
- 优先用
MSET或HMSET(Redis 4.0+ 改名HSET)一次塞多对键值,减少网络往返 - 高频写场景必须上
PIPELINE:客户端攒一批命令发过去,Redis 一次性解析执行,吞吐能提 5–10 倍 - 千万避开
KEYS *、SCAN配合大量DEL清理旧数据——这会阻塞主线程;改用UNLINK触发 lazy free
容易被忽略的两个隐性爆点
很多人调完 maxmemory-policy 就以为万事大吉,但真正压垮 Redis 的,往往是这两处:
-
maxmemory-samples默认是5,即每次淘汰只随机采样 5 个键来选“最不重要”的那个。数据量大时极易误杀热键。生产环境建议设为10~20,提升 LRU/LFU 决策质量 - 主从架构下,从节点读到过期键的“脏数据”不是配置问题,是机制使然——过期判断靠主节点惰性删除 + 定期扫描,从节点不主动删键。敏感业务得在应用层加时间戳校验,不能无脑信缓存值
淘汰不是故障,是常态;但频繁触发,说明写入节奏和内存治理没对齐。重点不在压住淘汰,而在让淘汰变得可预期、可收敛。


















