怎么看淘汰是否在发生
Redis 在内存达到 maxmemory 后按既定策略淘汰键,但这个过程是静默的:应用只会看到缓存命中率下降,实例不会报错。INFO stats 里的 evicted_keys 是累计淘汰数量,只要它在增长就说明确实在淘汰;配合 used_memory 与单个键的访问特征,可以判断策略选择是否与业务访问模式匹配。
基本信息
| 适用平台 | Redis 2.8+(LFU 需 4.0+) |
|---|---|
| 相关参数 | maxmemory、maxmemory-policy、maxmemory-samples |
| 观察字段 | evicted_keys、expired_keys、used_memory、used_memory_peak |
| 策略族 | allkeys-lru/lfu、volatile-lru/lfu、allkeys-random、noeviction |
| 辅助命令 | OBJECT IDLETIME、OBJECT FREQ |
典型使用场景
- 上线新缓存后确认淘汰策略是否按预期工作
- 缓存命中率下降时判断是容量不足还是键设计问题
- 切换 LRU 与 LFU 策略前后做效果对比
- 排查写入成功但读不到数据的现象是否由淘汰引起
- 容量规划:评估在现有内存下能保住的键规模
验证淘汰行为
验证淘汰行为
INFO stats | grep evicted_keys # 累计被淘汰的键数,只增不减
INFO stats | grep expired_keys # 自然过期的键数
INFO memory | grep -E 'used_memory_human|used_memory_peak_human|maxmemory_human'
CONFIG GET maxmemory-policy
# LRU 策略下观察单键空闲时间(秒)
OBJECT IDLETIME somekey
# LFU 策略下观察单键访问频率计数
OBJECT FREQ somekey
# 查看占用空间较大的键(低峰执行)
redis-cli --bigkeys指标对照
| 指标 | 含义 | 判断方法 |
|---|---|---|
| evicted_keys | 因内存不足被主动淘汰的键数 | 持续增长说明正在淘汰 |
| expired_keys | 因 TTL 到期被删除的键数 | 与淘汰是两回事,不要混看 |
| used_memory 与 maxmemory 的关系 | 内存水位 | 稳定贴近上限即处于持续淘汰状态 |
| used_memory_peak | 历史峰值 | 峰值远超当前值说明曾发生剧烈淘汰 |
| 命中率 | keyspace_hits 与 misses 的比值 | 与 evicted_keys 同向恶化说明容量不足 |
命中率下降与 evicted_keys 同步上升,通常先说明内存不够或键设计有问题:优先排查大 key、没有 TTL 的键,然后再考虑扩容。
把 maxmemory-policy 设为 noeviction 时内存写满会直接返回错误而不是淘汰:数据安全性更高,但写入路径必须有失败处理,否则业务会持续报错。
淘汰是概率行为而非精确排序:LRU 与 LFU 都通过采样近似实现,maxmemory-samples 越大越接近真实使用规律,代价是每次淘汰判定更费 CPU。小内存实例不必调大,大实例可以适度提高。