返回归档
📌Redis

Redis-内存过期和内存淘汰策略

文章目录

Redis是一个内存数据库,内存往往是有限的。同时缓存与真实数据也存在数据不一致问题,所以Redis中的数据往往会设置TTL(time-to-live)。

┌─────────┐
 设置 TTL
                └────┬────┘

      ┌──────────────┴──────────────┐

 ┌────▼────┐                    ┌────▼─────┐
 定期删除 │←——随机扫描——————————→│   惰性删除
 └────┬────┘                    └────┬─────┘


      └──────────────┬──────────────┘


          内存达到 maxmemory?

               Yes    No
                 ┌──────────┐
 内存淘汰 不触发
                 └──────────┘

重点:管理的是 被设置了 TTL 的 key 的生命周期

Redis 提供三种机制,用来处理已经过期的 key:

  1. 定期删除(periodic deletion)
    1. Redis 默认每100ms 执行一次“定期扫描”
    2. 随机抽取部分有设置TTL的key
    3. 对过期key删除
    4. 如果发现过期key占比较高,循环步骤c,但整体保证cpu低于25%,确保不会阻塞主线程
  2. 惰性删除(lazy deletion)
    1. 不会主动清理,只有key被client访问时执行,以节省CPU
  3. 内存淘汰策略(eviction)在达到 maxmemory 时强制删除
策略 触发时机 优点 缺点
定期删除 定时任务扫描 不积压过期 key 可能有延迟删除
惰性删除 查询 key 时 CPU 成本最低 未被访问的 key 会一直占内存
内存淘汰 内存不足触发 防止 OOM 属于紧急措施

内存淘汰策略

按照key的类别来看

  1. allkeys-* 表示所有key
  2. volatile-* 表示有设置TTL的

从筛选的策略角度看

  1. lru
  2. lfu
  3. random
  4. ttl
策略名 删除范围 逻辑 特点
volatile-lru 仅 TTL key LRU 删除 比较温和
allkeys-lru 所有 key LRU 删除 缓存场景最常用
volatile-lfu 仅 TTL key 删除访问次数最低 适合频率敏感业务
allkeys-lfu 所有 key 删除访问次数最低 Redis 4.0 起最推荐
volatile-random 仅 TTL key 随机删 简单粗暴
allkeys-random 所有 key 随机删 适合极端性能要求
volatile-ttl 仅 TTL key 删除 TTL 最短(最先过期) 适合同 TTL 场景
noeviction 不删除 直接报错 防止数据丢失

生产的最佳实践

从缓存的核心来看问题

  1. 热数据需要保存在内存中
  2. 冷数据需要被淘汰
  • 对于高并发缓存场景:allkeys-lru比较合适。LRU反映 “最近没被访问”,贴合业务。
  • **会话、登录态场景:**volatile-lru比较合适。session数据都设置了TTL,只希望淘汰“会过期”的数据
  • 高频访问系统(计数器、热点 API):allkeys-lfu(趋势策略)。LFU能识别“访问频率非常高”的数据,优于LRU。
  • **避免使用random,**除非极端性能追求
  • 为了防止redis OOM,一定要配置好maxMemory