redis键的过期时间都保存在过期字典中,根据系统时间和存活时间判断是否过期。redis有三种不同的删除策略:定时删除、惰性删除、定期删除。

1.定时删除

  • 属于主动删除
  • 在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作
  • 对内存友好,但是对cpu很不友好
  • 删除策略由activeExpireCycle算法决定,遍历数据库,如果时间到,则终止;遍历数据库接着上次的进度,直到所有数据库遍历完,再接着遍历;遍历库时候,随机取出一定数量的随机键

2.惰性删除

  • 属于被动删除
  • 放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键
  • 对cpu友好,对内存很不友好
  • 惰性删除策略由expireIfNeeded函数实现,所有读写数据库的Redis命令在执行之前,都会调用expireIfNeeded函数对输入键进行检查:
  • 如果输入键已经过期,那么expireIfNeeded函数将输入键从数据库中删除。
  • 如果输入键未过期,那么expireIfNeeded函数不做动作。
  • expireIfNeeded函数就像一个过滤器,它可以在命令真正执行之前,过滤掉过期的输入键,从而避免命令接触到过期键。
  • 因为每个被访问的键都可能因为过期而被expireIfNeeded函数删除,所以每个命令的实现函数都必须能同时处理键存在以及键不存在这两种情况:
  • 当键存在时,命令按照键存在的情况执行。
  • 当键不存在或者键因为过期而被expireIfNeeded函数删除时,命令按照键不存在的情况执行。

3.定期删除

  • 主动删除
  • 每隔一段时间,对数据库进行一次检查,删除过期键,由算法决定删除多少过期键和检查多少数据库
  • 是定时删除和惰性删除的折中,如果删除太频繁,将退化为定时删除,如果删除次数太少,将退化为惰性删除。

4.主动删除

定时删除和定期删除都是主动删除策略,由于惰性删除策略无法保证冷数据被及时删掉,所以redis会定期主动删除一批已过期的key。当前已用内存超过maxmemory限定时,触发主动清理策略,策略包含以下几种

  • volatile-random:从设置了过期时间的键中,随机选择键进行清除
  • volatile-ttl:从设置了过期时间的键中选择过期时间最早的键值对清除
  • volatile-lru:最近最少使用算法,从设置了过期时间的键中选择空转时间最长的键值对清除掉
  • volatile-lfu:最近最不经常使用算法,从设置了过期时间的键中选择某段时间之内使用频次最小的键值对清除掉
  • allkeys-lru:最近最少使用算法,从所有的键中选择空转时间最长的键值对清除
  • allkeys-lfu:最近最不经常使用算法,从所有的键中选择某段时间之内使用频次最少的键值对清除
  • allkeys-random:所有的键中,随机选择键进行删除
  • noeviction:不做任何的清理工作,在redis的内存超过限制之后,所有的写入操作都会返回错误,但是读操作都能正常的进行

redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好地在合理使用CPU时间和避免浪费内存空间之间取得平衡。