淘汰策略介绍

image.png

## 淘汰策略
### 前置知识
- 淘汰算法
  - LRU(最近最少使用)
    - 核心:淘汰最长时间未被访问的数据
    - 不适合查找历史记录/遍历
    - 借助 LinkedHashMap 易实现
  - LFU(最不经常使用)
    - 核心:淘汰访问次数最少的数据
    - 统计范围:全部访问次数/指定时间段内次数
- Redis 淘汰策略(内存满时触发)
  - volatile-ttl:过期key中按剩余TTL(生存时间)淘汰
  - volatile-lru:过期key中按LRU规则淘汰
  - volatile-lfu:过期key中按LFU规则淘汰
  - volatile-random:过期key中随机淘汰
  - allkeys-ttl:所有key中按剩余TTL淘汰
  - allkeys-lru:所有key中按LRU规则淘汰
  - allkeys-lfu:所有key中按LFU规则淘汰
  - allkeys-random:所有key中随机淘汰
  - noeviction:不淘汰,内存满则写操作报错
  - 说明:带volatile→仅从过期key选;带allkeys→从所有key选
### Redis 上控制业务缓存使用量
- 基本操作:lua脚本实现(保证原子性)
- 核心思路
  - 控制键值对数量上限
  - 控制单个键值对大小上限
- 执行步骤
  - 用Redis独立键存储当前键值对计数
  - 新增键值对时,先检测是否超上限
    - 未超:更新计数,写入新键值对
  - 监听键删除事件(DEL/过期),同步递减计数
### 亮点方案:按优先级淘汰
- 优先级规则(可自定义计算逻辑)
  - 大对象优先:单key占用空间大,淘汰后腾出更多内存
  - 小对象优先:小对象计算/重建成本低,淘汰代价小
  - 代价优先:按CPU/IO等系统资源消耗程度排序淘汰
  - 低热度优先:热度低(访问少)的key优先淘汰,类似长过期时间逻辑
- Redis落地(lua脚本保证原子性)
  - 用zset(有序集合)存储key与对应优先级分数
  - 新增键值对:先检测zset元素数是否超上限
    - 未超:写入键值对,同时将key+优先级分数加入zset
  - 触发淘汰:从zset中删除优先级最低(分数最小)的第一个元素

Redis默认淘汰策略

Redis 版本 默认淘汰策略 说明
3.0 之前 volatile-lru 仅在设置了过期时间的键中,按照 “最近最少使用” 规则淘汰。
3.0 及之后 noeviction 内存超出上限时不淘汰任何键,新写入操作会报错(删除、查询操作不受影响)。
4.0 及之后(LFU 相关) 无变更(默认仍为 noeviction 4.0 新增 allkeys-lfu 和 volatile-lfu 策略,但默认策略未改变。
特殊场景(Active-Active 数据库) noeviction Redis 企业版的 Active-Active 数据库默认采用此策略。