Redis 内存淘汰策略 就是:当 Redis 使用内存超过 maxmemory 限制时,Redis 按什么规则删除 key,给新数据腾空间。
核心配置是两个:
conf
maxmemory 512mb
maxmemory-policy allkeys-lru
常见淘汰策略
| 策略 | 含义 |
|---|---|
noeviction |
不淘汰 key,内存满后写入报错 |
allkeys-lru |
从所有 key 中淘汰最近最少使用的 key |
volatile-lru |
从设置了过期时间的 key 中淘汰最近最少使用的 key |
allkeys-lfu |
从所有 key 中淘汰使用频率最低的 key |
volatile-lfu |
从设置了过期时间的 key 中淘汰使用频率最低的 key |
allkeys-random |
从所有 key 中随机淘汰 |
volatile-random |
从设置了过期时间的 key 中随机淘汰 |
volatile-ttl |
从设置了过期时间的 key 中优先淘汰快过期的 key |
几个关键词
LRU :Least Recently Used,最近最少使用。
谁最近最久没被访问,就先淘汰谁。
LFU :Least Frequently Used,最少频率使用。
谁访问次数少,就先淘汰谁。
volatile :只淘汰设置了过期时间的 key。
如果没有设置 TTL 的 key,就不会被淘汰。
allkeys :所有 key 都可能被淘汰。
不管有没有设置过期时间。
面试里重点比较
| 对比 | 区别 |
|---|---|
allkeys-lru vs volatile-lru |
前者所有 key 都能淘汰,后者只淘汰有 TTL 的 key |
LRU vs LFU |
LRU 看最近是否访问,LFU 看访问频率 |
noeviction |
内存满后不删数据,写请求可能失败 |
一般怎么选?
如果 Redis 主要就是缓存,推荐:
conf
allkeys-lru
或者:
conf
allkeys-lfu
原因是缓存数据本来就允许被淘汰,Redis 可以自动保留更热的数据。
如果 Redis 里混有不能丢的数据,比如分布式锁、计数器、业务状态,就不能随便用 allkeys-*,否则可能把关键 key 淘汰掉。更稳妥的方式是:
conf
volatile-lru
并且只给缓存类 key 设置 TTL。
结合黑马点评项目
店铺详情、优惠券列表这种数据属于缓存,可以接受被淘汰后重新查库加载。
但像秒杀库存、用户登录 token、分布式锁这类 key,就不能随便被 Redis 淘汰,否则会影响业务正确性。
所以项目里可以这样说:
如果 Redis 主要承担缓存角色,可以使用
allkeys-lru或allkeys-lfu,让 Redis 在内存不足时自动淘汰冷数据。但如果 Redis 中同时存了业务关键数据,比如分布式锁、登录态、秒杀库存,就要避免使用会淘汰所有 key 的策略,最好把缓存和关键数据隔离到不同 Redis 实例或不同库,并对缓存 key 设置 TTL,使用volatile-lru这类策略。
面试回答版
Redis 内存淘汰策略是指 Redis 达到
maxmemory后如何删除 key。常见策略有noeviction、allkeys-lru、volatile-lru、allkeys-lfu、volatile-lfu、随机淘汰和按 TTL 淘汰。如果 Redis 只作为缓存,一般选择
allkeys-lru或allkeys-lfu,自动淘汰冷数据;如果 Redis 里还有分布式锁、库存、登录态等关键数据,就不能让所有 key 都参与淘汰,最好做实例隔离,或者只让设置了过期时间的缓存 key 参与淘汰。