总结
Redis提供多种缓存淘汰策略,包括:volatile-lru(针对过期键的LRU淘汰)、allkeys-lru(全体键LRU)、volatile-lfu(过期键LFU)、allkeys-lfu(全体键LFU)、volatile-ttl(优先淘汰剩余时间短的键)、volatile-random/ allkeys-random(随机淘汰),以及默认的noeviction(禁止写入)。策略根据内存上限自动触发,用于管理内存不足时的数据清理。
详细解析
Redis 的 缓存淘汰策略(Eviction Policy)用于在内存不足时(达到maxmemory限制)选择哪些键(key)被删除以释放空间。其策略通过maxmemory-policy配置,以下是 Redis 支持的淘汰策略及其核心逻辑:
1. 淘汰策略分类
Redis 淘汰策略分为 键范围 和 淘汰算法 两个维度:
键范围
- allkeys-*:所有键都可能被淘汰(包括未设置过期时间的键)。
- volatile-*:仅淘汰设置了过期时间(TTL)的键。
淘汰算法
- LRU(Least Recently Used):淘汰最久未使用的键。
- LFU(Least Frequently Used):淘汰访问频率最低的键(Redis 4.0+)。
- TTL:淘汰剩余过期时间最短的键。
- Random:随机淘汰。
2. 具体策略详解
策略名称 | 规则 | 适用场景 |
---|---|---|
noeviction | 不淘汰任何键,内存满时新写入操作返回错误(默认策略)。 | 数据不可丢失,需严格内存控制。 |
allkeys-lru | 从所有键中选择最久未使用的键淘汰。 | 通用缓存场景(推荐)。 |
volatile-lru | 从设置了 TTL 的键中选择最久未使用的键淘汰。 | 部分数据允许过期。 |
allkeys-lfu | 从所有键中选择访问频率最低的键淘汰(Redis 4.0+)。 | 热点数据缓存,区分冷热数据。 |
volatile-lfu | 从设置了 TTL 的键中选择访问频率最低的键淘汰(Redis 4.0+)。 | 需要结合 TTL 管理冷数据。 |
allkeys-random | 从所有键中随机淘汰。 | 无明确访问模式,简单快速。 |
volatile-random | 从设置了 TTL 的键中随机淘汰。 | 随机淘汰过期数据。 |
volatile-ttl | 从设置了 TTL 的键中淘汰剩余存活时间最短的键。 | 优先清理即将过期的数据。 |
3. 策略选择建议
缓存场景(允许数据丢失)
- 优先选择allkeys-lru或allkeys-lfu:利用访问模式淘汰冷数据。
- 若数据访问频率差异大:使用allkeys-lfu更精准(如热点文章、商品)。
持久化数据(不允许丢失)
- 使用noeviction:避免误删数据,但需监控内存,防止写操作失败。
混合场景(部分数据可过期)
- volatile-lru+ 设置 TTL:结合过期时间管理临时数据(如用户会话)。
特殊需求
- 快速淘汰:allkeys-random或volatile-random(性能高但不够精准)。
- 清理即将过期的键:volatile-ttl(如促销活动临时数据)。
4. LRU 与 LFU 的实现优化
Redis 未使用标准 LRU/LFU 算法,而是通过近似算法降低内存和计算开销:
- LRU 近似:记录键的最近访问时间戳(精度为秒),淘汰时采样少量键(默认5个),选择最旧的。
- LFU 近似:使用计数器(范围 0~255),按概率衰减计数器值,优先淘汰计数器低的键。
LFU 计数器衰减配置
- 通过lfu-decay-time设置计数器衰减周期(默认1分钟),控制访问频率的时效性。
5. 配置示例
1 2 3 4 |
|
6. 淘汰策略工作原理
- 触发条件:执行写入命令(如SET)时,若内存超过maxmemory,触发淘汰。
- 执行过程:
- 根据策略选择候选键。
- 删除键并释放内存。
- 若释放后仍不足,重复淘汰直到满足内存要求。
总结
策略 | 核心逻辑 | 适用场景 | 注意点 |
---|---|---|---|
allkeys-lru | 淘汰最久未使用的键 | 通用缓存 | 对访问模式敏感 |
allkeys-lfu | 淘汰访问频率最低的键 | 热点数据场景 | 需 Redis 4.0+ |
volatile-ttl | 淘汰最快过期的键 | 临时数据管理 | 依赖合理设置 TTL |
noeviction | 禁止淘汰,直接报错 | 数据不可丢失场景 | 需严格监控内存 |
根据业务场景选择合适策略,并结合监控工具(如INFO memory)观察淘汰效果,必要时调整策略或优化数据访问模式