欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Redis 对过期数据的处理方法

程序员文章站 2022-04-22 20:37:13
在 redis 中,对于已经过期的数据,redis 采用两种策略来处理这些数据,分别是惰性删除和定期删除惰性删除惰性删除不会去主动删除数据,而是在访问数据的时候,再检查当前键值是否过期,如果过期则执行...

在 redis 中,对于已经过期的数据,redis 采用两种策略来处理这些数据,分别是惰性删除和定期删除

惰性删除

惰性删除不会去主动删除数据,而是在访问数据的时候,再检查当前键值是否过期,如果过期则执行删除并返回 null 给客户端,如果没有过期则返回正常信息给客户端。

它的优点是简单,不需要对过期的数据做额外的处理,只有在每次访问的时候才会检查键值是否过期,缺点是删除过期键不及时,造成了一定的空间浪费。

源码

定期删除

定期删除:redis会周期性的随机测试一批设置了过期时间的key并进行处理。测试到的已过期的key将被删除。

具体的算法如下:

  • redis配置项hz定义了servercron任务的执行周期,默认为10,代表了每秒执行10次;
  • 每次过期key清理的时间不超过cpu时间的25%,比如hz默认为10,则一次清理时间最大为25ms;
  • 清理时依次遍历所有的db;
  • 从db中随机取20个key,判断是否过期,若过期,则逐出;
  • 若有5个以上key过期,则重复步骤4,否则遍历下一个db;
  • 在清理过程中,若达到了25%cpu时间,退出清理过程;

虽然redis的确是不断的删除一些过期数据,但是很多没有设置过期时间的数据也会越来越多,那么redis内存不够用的时候是怎么处理的呢?这里我们就会谈到淘汰策略

redis内存淘汰策略

当redis的内存超过最大允许的内存之后,redis会触发内存淘汰策略,删除一些不常用的数据,以保证redis服务器的正常运行

在redis 4.0以前,redis的内存淘汰策略有以下6种

  • noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键
  • allkeys-lru:加入键的时候,如果过限,首先通过lru算法驱逐最久没有使用的键
  • volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键
  • allkeys-random:加入键的时候如果过限,从所有key随机删除
  • volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐
  • volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键
  • 在redis 4.0以后,又增加了以下两种
  • volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键
  • allkeys-lfu:从所有键中驱逐使用频率最少的键

内存淘汰策略可以通过配置文件来修改,redis.conf对应的配置项是maxmemory-policy 修改对应的值就行,默认是noeviction

lru(the least recently used 最近最少使用)算法

如果一个数据在最近没有被访问到,那么在未来被访问的可能性也很小,因此当空间满的时候,最久没有被访问的数据最先被置换(淘汰)

lru算法通常通过双向链表来实现,添加元素的时候,直接插入表头,访问元素的时候,先判断元素是否在链表中存在,如果存在就把该元素移动至表头,所以链表的元素排列顺序就是元素最近被访问的顺序,当内存达到设置阈值时,lru队尾的元素由于被访问的时间线较远,会优先踢出

Redis 对过期数据的处理方法

Redis 对过期数据的处理方法

但是在redis中,并没有严格实行lru算法,之所以这样是因为lru需要消耗大量的额外内存,需要对现有的数据结构进行较大的改造,近似lru算法采用在现有数据结构的基础上使用随机采样法来淘汰元素,能达到和lru算法非常近似的效果。redis的 lru算法给每个key增加了一个额外的长度为24bit的小字段,记录最后一次被访问的时间戳。

redis通过maxmemory-samples 5配置,对key进行采样淘汰。同时在redis3.0以后添加了淘汰池进一步提升了淘汰准确度。

但是lru算法是存在一定的问题

例如,这表示随着时间的推移,四个不同的键访问。每个“〜”字符为一秒钟,而“ |” 最后一行是当前时刻。

到此这篇关于redis 对过期数据的处理方法的文章就介绍到这了,更多相关redis过期数据的处理内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关标签: Redis 过期数据