Redis 数据淘汰机制概览
当 Redis 使用内存达到配置的 maxmemory 上限时,会根据 maxmemory-policy 执行淘汰,以腾出空间给新写入。该机制用于缓存场景在内存紧张时自动取舍数据,避免进程因 OOM 而异常。Redis 提供 8 种策略,核心权衡维度是:淘汰范围(仅限设置了 TTL 的键,还是全量键)与淘汰依据(LRU、LFU、随机、TTL 剩余最短)。
策略一览
| 策略 |
淘汰范围 |
依据 |
典型场景 |
| noeviction |
无 |
不淘汰,直接拒绝写入 |
数据不可丢、可接受写入失败 |
| allkeys-lru |
全量键 |
最近最少使用 |
访问呈幂律分布、希望保留热点 |
| allkeys-lfu |
全量键 |
最不常用(访问频次) |
访问频次差异明显 |
| volatile-lru |
仅设 TTL 的键 |
最近最少使用 |
明确哪些数据可被淘汰 |
| volatile-lfu |
仅设 TTL 的键 |
最不常用 |
TTL 数据且关注访问频次 |
| allkeys-random |
全量键 |
随机 |
访问分布均匀、实现简单 |
| volatile-random |
仅设 TTL 的键 |
随机 |
TTL 数据且不在意命中分布 |
| volatile-ttl |
仅设 TTL 的键 |
剩余 TTL 最短 |
希望尽快释放即将过期的数据 |
| 说明:volatile-* 策略仅在存在可淘汰键时生效;若没有可淘汰键,行为等同于 noeviction。 |
|
|
|
触发时机与执行流程
- 每次执行命令前,Redis 会检查是否超过 maxmemory;若超过,则调用 freeMemoryIfNeeded 尝试释放内存(先尝试回收过期键,再按策略淘汰)。
- 若策略为 noeviction 或没有可淘汰键,写入命令将被拒绝并返回 OOM command not allowed when used memory 错误。
- 淘汰只影响内存占用,不会主动触发持久化;但被淘汰键的删除会按持久化配置(如 AOF)记录并传播到从节点。
如何选择策略
- 大多数缓存场景优先用 allkeys-lru(热点数据更可能保留)。
- 访问频次差异显著时用 allkeys-lfu。
- 数据天然具备 TTL 且希望由 Redis 自动清理时,用 volatile-lru / volatile-lfu / volatile-ttl;若没有设置 TTL,这些策略将退化为不淘汰。
- 访问非常均匀或实现简单优先时,用 allkeys-random / volatile-random。
- 对数据完整性要求极高、宁可写入失败也不淘汰时,用 noeviction。
运行时可结合 INFO 的 keyspace_hits / keyspace_misses 观察命中率并动态调参。
配置方法与注意事项
- 配置方式
- 配置文件:设置
maxmemory 100mb
maxmemory-policy allkeys-lru
- 动态命令:
CONFIG SET maxmemory 100mb
CONFIG SET maxmemory-policy allkeys-lru
- 注意事项
- 使用 volatile-* 策略前务必为需要可被淘汰的键设置 TTL,否则这些键永远不会被该策略选中。
- 在 noeviction 下,超过内存上限将返回 OOM 错误,需评估对业务可用性的影响。
- 淘汰是“尽力而为”的取舍,并非严格意义上的全局最优;结合监控持续调优更可靠。