内存满了怎么腾地方
maxmemory-policy 决定内存到达上限后 Redis 的取舍:不淘汰就直接拒绝写入,全部键范围与仅带过期时间范围各有一套规则,淘汰依据分最近最少使用、访问频率最低、随机与剩余存活时间最短四种。其中两种基于访问统计的策略都是抽样近似实现,随机策略 CPU 开销最低。
基本信息
| 默认值 | noeviction |
|---|---|
| 生效前提 | 必须设置 maxmemory,为 0 时表示不限内存、策略不会生效 |
| 采样精度 | maxmemory-samples,默认 5,越大越接近真实统计 |
| 查看与设置 | CONFIG GET / CONFIG SET maxmemory、maxmemory-policy |
八种策略对照
| 策略 | 淘汰范围 | 淘汰依据 | 典型场景 |
|---|---|---|---|
| noeviction | 不淘汰 | 内存满后写命令报错 | 需要严格不丢数据且能及时扩容 |
| allkeys-lru | 全部键 | 最近最少使用 | 通用缓存,命中率优先 |
| allkeys-lfu | 全部键 | 访问频率最低 | 访问分布长期稳定、长尾明显的缓存 |
| allkeys-random | 全部键 | 随机 | 访问均匀或不在意命中率 |
| volatile-lru | 仅带过期时间的键 | 最近最少使用 | 永久键与可丢键混存的实例 |
| volatile-lfu | 仅带过期时间的键 | 访问频率最低 | 带过期时间的长尾缓存 |
| volatile-random | 仅带过期时间的键 | 随机 | 结构简单、CPU 最省的场景 |
| volatile-ttl | 仅带过期时间的键 | 剩余存活时间最短 | 希望优先释放即将过期的数据 |
选型建议
- 纯缓存实例:全部键都可丢时用 allkeys-lru,不必为每个键设计过期时间
- 冷热分明且分布稳定:可评估 allkeys-lfu,但需要预热与频率统计周期
- 会话类数据:键普遍带过期时间时用 volatile-lru 或 volatile-ttl,未设过期时间的键不会被动
- 队列或不可丢数据:用 noeviction 并配套内存告警与扩容流程
设置示例
设置示例
redis-cli CONFIG GET maxmemory maxmemory-policy # 先确认到底限没限内存
redis-cli CONFIG SET maxmemory 4gb # 第一步:设置内存上限
redis-cli CONFIG SET maxmemory-policy allkeys-lru # 第二步:选择淘汰策略
redis-cli CONFIG SET maxmemory-samples 10 # 提高采样精度,代价是 CPU
redis-cli INFO stats | grep evicted_keys # 观察淘汰是否真的在发生
redis-cli CONFIG REWRITE # 固化到配置文件volatile 系策略在没有任何键带过期时间、或可淘汰的键已耗尽时,行为等同 noeviction,写命令会直接报错。缓存实例误配成 volatile-lru 而数据全不带过期时间,是线上写入失败的常见原因。
两种基于访问统计的策略都是抽样比较,不是精确计算,偶发淘汰掉刚用过的键属于正常现象。频率策略还受计数器衰减参数影响,长期不被访问的键计数会回落。
noeviction 下内存满后的典型报错是 OOM command not allowed when used memory > 'maxmemory':读命令仍可用,写入全部失败,需要靠扩容或调整淘汰策略解决。