改淘汰策略是最快见效的手段,但不能替代扩容;如果业务写入持续增长、冷热数据混杂、或已有大量无过期时间的键,光调策略只是拖延问题——该扩容还得扩容。

直接说结论:**改淘汰策略是最快见效的手段,但不能替代扩容;如果业务写入持续增长、冷热数据混杂、或已有大量无过期时间的键,光调策略只是拖延问题——该扩容还得扩容。**
为什么改淘汰策略能立刻缓解 OOM 错误
Redis 内存满时返回 OOM command not allowed when used memory > 'maxmemory',本质是 maxmemory-policy 为默认的 noeviction,拒绝所有写入。只要改成任意一种淘汰策略(比如 allkeys-lru),Redis 就会开始主动删键腾空间,写操作立刻恢复。
- 执行
CONFIG SET maxmemory-policy allkeys-lru后,下一次写入触发内存超限时,Redis 会随机采样maxmemory-samples(默认 5)个键,淘汰其中最久未使用的那个——不是全量扫描,开销可控 - 如果业务中大部分键都带
EX或PEXPIRE,优先用volatile-lru或volatile-ttl,避免误删长期有效的配置类数据 - 注意:
volatile-*系列策略在没有带过期时间的键时,会退化成noeviction行为(即继续报 OOM),这点极易被忽略
哪些淘汰策略容易踩坑
选错策略可能让缓存命中率断崖下跌,甚至引发雪崩。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
volatile-random和allkeys-random:完全不看访问模式,纯靠运气删键。在热点数据集里等于主动制造缓存穿透 -
volatile-ttl:适合日志类短期数据,但如果业务里大量键设置的是固定长 TTL(比如全部设 24h),那它们剩余 TTL 差距极小,实际淘汰效果接近随机 -
allkeys-lfu:比 LRU 更适合长期稳定访问模式(如用户画像),但 Redis 的 LFU 实现有衰减机制(lfu-log-factor控制),新写入的键初始计数低,可能刚写进去就被淘汰——需调大lfu-log-factor(默认 10)并观察
什么时候必须扩容,而不是只调策略
淘汰策略解决的是“删谁”,不是“为什么总要删”。以下信号说明策略已到极限:
- 监控
INFO memory中的evicted_keys持续上涨(比如每秒几百次),说明 Redis 大部分时间都在忙于淘汰,吞吐和延迟都会恶化 -
used_memory_rss/used_memory> 1.5:内存碎片严重,淘汰释放的空间很快又被碎片吃掉,此时应先MEMORY PURGE或重启(若允许) - 业务中存在大量 MB 级
String或Hash(用redis-cli --bigkeys可查),这类大 Key 单次淘汰成本高,且容易阻塞主线程——拆分比换策略更治本 - 集群环境下单节点内存长期 > 15GB:Redis 单实例内存上限建议控制在 10–20GB 区间,再往上扩,主从同步、RDB 生成、AOF rewrite 都会明显变慢
线上临时救急和长期优化的分工
别把临时手段当长期方案。
- 救急:立刻执行
CONFIG SET maxmemory 2gb(如果还没设)+CONFIG SET maxmemory-policy allkeys-lfu,配合CONFIG REWRITE持久化 - 定位:用
MEMORY USAGE keyname查具体大 Key,用OBJECT FREQ(LFU)或OBJECT IDLETIME(LRU)验证访问模式是否匹配所选策略 - 长期:对非缓存类数据(如全局配置、用户基础信息)显式不设 TTL;对缓存类数据统一加 TTL,并按业务生命周期分级(会话 30m、商品页 2h、推荐结果 6h)
真正难的不是选哪个策略,而是搞清你的数据里哪些是“可丢的缓存”、哪些是“丢了就炸的配置”——这个边界一旦模糊,再好的淘汰算法也救不了。

















