Redis过期删除策略与内存淘汰机制

过期删除策略

过期删除策略主要有以下三种:

  • 定时删除:设置过期时间的同时,创建一个定时器,当到达过期时间后,执行删除操作。
    • 优点:对内存友好,不会长时间占用内存
    • 缺点:对CPU不友好,当过期entry过多会占用大量CPU时间,并且创建定时器存在性能消耗。
  • 惰性删除:每次查询到该entry时,检查是否过期,若过期就删除,否则返回。
    • 优点:对CPU友好
    • 缺点:无用数据占用大量内存空间,依赖于客户端请求对过期数据进行删除。有内存泄漏的风险。
  • 定期删除:每隔一段时间对数据库进行检查,删除其中的过期entry。
    • 综合考虑上述策略的优缺点,可以合理设置执行时长和频率。

Redis中主要配合使用惰性删除定期删除两种策略,在内存和CPU性能中取得平衡。 使用过期字典存储所有key的过期时间。key是一个指针,指向key对象,value是一个long long类型的整数,保存key的过期时间。

实现:

  • 惰性删除:db.c/expireIfNeeded在读写之前对key进行检查.
  • 定期删除:redis.c/activeExpireCycle实现,每当Redis的serverCron执行时,都会主动清除过期数据。
    • activeExpireCycle的工作流程如下:
      • 每次取出一定数量的随机key进行检查,并删除其中的过期数据
      • 全局变量current_db存储当前的检查进度(db编号),并且下次activeExpireCycle执行会接着上次进度进行处理。全部检查完毕后该变量置为0。

内存淘汰策略

当Redis的运行内存已经超过设置的最大内存时,会使用内存淘汰策略删除符合相关条件的key。 最大内存通过设置maxmemory <bytes>即可。默认为0,表示没有内存大小的限制。

Redis的内存淘汰策略如下:

  • 不淘汰
    • noeviction:不淘汰任何数据、直接返回错误。
  • 对设置了过期时间的数据进行淘汰
    • volatile-random: 随意淘汰设置了过期时间的任意entry。
    • volatile-ttl:优先淘汰更早过期的entry。
    • volatile-lru:淘汰所有设置了过期时间的entry中最近最久未使用的entry。
    • volatile-lfu:淘汰所有设置了过期时间的entry中最少使用的entry。
  • 对全部数据进行淘汰
    • allkeys-random:随即淘汰任意entry。
    • allkeys-lru:使用LRU策略淘汰任意entry。
    • allkeys-lfu:使用LFU策略淘汰任意entry。

修改redis.conf中的maxmemory-policy <策略>即可。


Redis过期删除策略与内存淘汰机制
https://l1n.wang/2020/中间件/Redis/Redis过期删除策略与内存淘汰机制/
作者
Lin Wang
发布于
2020年7月10日
许可协议