关注分享主机优惠活动
国内外VPS云服务器

redis过期密钥删除策略(Redis过期删除策略)的原理解释

本文介绍了Redis的一些知识,主要介绍了Redis过期密钥删除策略的原理。Redis服务器实际上使用了两种策略:懒惰删除和定期删除。通过将这两种删除策略结合使用,服务器可以在合理使用CPU时间和避免浪费内存空间之间达到很好的平衡。希望对你有帮助。

redis过期密钥删除策略(Redis过期删除策略)的原理解释-主机频道

推荐:Redis视频教程

Redis服务器实际上使用了两种策略:惰性删除和周期性删除。通过同时使用这两种删除策略,服务器可以在合理使用CPU时间和避免浪费内存空间之间取得良好的平衡。

Delete lazy delete策略对CPU时间最友好:程序在取出密钥时只会检查密钥是否过期,可以保证删除过期密钥的操作只在必要的时候进行,删除目标仅限于当前正在处理的密钥。这种策略不会在删除其他不相关的过期密钥上花费任何CPU时间。

惰性删除策略的缺点是它是最不友好的内存:如果一个键已经过期,而这个键还留在数据库中,那么过期键占用的内存只要不被删除就不会被释放。

在使用惰性删除策略时,如果数据库中有很多过期的键,而这些过期的键恰好没有被访问,那么它们可能永远不会被删除(除非用户手动执行FLUSHDB)。我们甚至可以把这种情况看作是内存泄漏——无用的垃圾数据占用了大量内存,但是服务器不会自己释放它们,这对于运行状态非常依赖内存的Redis服务器来说绝对不是什么好消息。

例如,对于一些与时间相关的数据,比如日志,在某个时间点之后,对它们的访问就会大大减少,甚至停止。如果数据库中积累了大量这样的过期数据,用户以为是服务器自动删除了,而实际上这些键还存在,键占用的内存没有释放,那么后果会很严重。

常规删除从上面对懒人删除的讨论来看,这种删除方式在单独使用时有明显的缺陷:

懒删除浪费内存太多,有内存泄露的风险。定期删除策略是前两种策略的集成和折衷:

定期删除策略每隔一段时间删除一次过期密钥,通过限制删除的持续时间和频率来减少删除对CPU时间的影响。此外,通过定期删除过期的密钥,定期删除策略有效地减少了因密钥过期而造成的内存浪费。周期性删除策略的难点在于确定删除的持续时间和频率:

如果删除操作执行过于频繁或时间过长,则周期性删除策略会退化为周期性删除策略,从而消耗过多的CPU时间来删除过期的密钥。

如果删除操作执行得太少或时间太短,常规删除策略将像惰性删除策略一样浪费内存。因此,如果采用周期性删除策略,服务器必须根据情况合理设置删除操作的执行时间和频率。

过期密钥的惰性删除策略由db . c/expire ifneed函数实现。所有用于读写数据库的Redis命令都将调用expirefeeded函数,在执行之前检查输入键:

如果输入密钥已经过期,expireIfNeeded函数将从数据库中删除输入密钥。

如果输入键没有过期,则expireIfNeeded函数不起作用。

redis过期密钥删除策略(Redis过期删除策略)的原理解释-主机频道

过期函数就像一个过滤器,可以在命令实际执行之前过滤掉过期的输入键,从而防止命令接触到过期的键。

此外,因为每个被访问的密钥都可能因为其过期而被expireIfNeeded函数删除,所以每个命令的实现函数必须能够处理密钥的存在和密钥的不存在:

当密钥存在时,根据密钥的存在执行命令。

当密钥不存在或者由于密钥过期而被expireIfNeeded函数删除时,根据密钥不存在来执行命令。

redis过期密钥删除策略(Redis过期删除策略)的原理解释-主机频道

定期删除策略的实现过期密钥的定期删除策略是通过redis.c/activeExpireCycle函数实现的。每当Redis的服务器周期性地运行redis.c/serverCron函数时,就会调用activeExpireCycle函数。它在指定的时间内多次遍历服务器中的每个数据库,从数据库的expires字典中随机检查一些密钥的过期时间,并删除过期的密钥。

整个过程可以用伪代码描述如下

redis过期密钥删除策略(Redis过期删除策略)的原理解释-主机频道

activeExpireCycle函数的工作模式可以总结如下:

函数每次运行时,从一定数量的数据库中取出一定数量的随机密钥进行校验,过期的密钥被删除。

全局变量current_db记录了当前activeExpireCycle函数检查的进度,将在下次调用activeExpireCycle函数时进行处理,后面是之前的进度。例如,如果当前的activeExpireCycle函数在遍历第10个数据库时返回,则下次执行activeExpireCycle函数时,将从第11个数据库中搜索并删除过期的密钥。

随着activeExpireCycle函数的不断执行,服务器中的所有数据库都会被检查一次。此时,该函数将current_db变量重置为0,然后再次开始新一轮的检查。

当服务器以复制模式运行时,从服务器中删除过期密钥的操作由主服务器控制:

删除过期的密钥后,主服务器将明确地向所有从服务器发送DEL命令,告诉它们删除过期的密钥。

从服务器在执行客户端发送的read命令时,即使遇到过期的密钥,也不会删除过期的密钥,而是继续像对待未过期的密钥一样对待过期的密钥。

从服务器只有在从主服务器接收到DEL命令后才会删除过期的密钥。

主服务器控制从服务器统一删除过期密钥,可以保证主服务器和从服务器数据的一致性。因此,当主服务器的数据库中仍然存在过期密钥时,从服务器中过期密钥的副本将继续存在。比如有一对主从服务器,它们的数据库都保存着相同的三个密钥message,xxx和yyy,其中message是过期的密钥,如图所示。

redis过期密钥删除策略(Redis过期删除策略)的原理解释-主机频道

此时,如果客户端向从服务器发送GET消息命令,从服务器会发现消息密钥已经过期,但从服务器不会删除消息密钥,而是继续向客户端返回消息密钥的值,就像消息密钥没有过期一样。

redis过期密钥删除策略(Redis过期删除策略)的原理解释-主机频道

假设在此之后,一个客户端向主服务器发送GET message命令,那么主服务器会发现密钥消息已经过期:主服务器会删除消息密钥,向客户端返回一个空回复,并向从服务器发送DEL message命令。

redis过期密钥删除策略(Redis过期删除策略)的原理解释-主机频道

从主服务器收到DEL message命令后,从服务器也会从数据库中删除消息密钥。之后,主服务器和从服务器将不再保存过期的密钥消息。

redis过期密钥删除策略(Redis过期删除策略)的原理解释-主机频道

推荐:Redis视频教程

前端(vue)入门到精通课程:立即学习

未经允许不得转载:主机频道 » redis过期密钥删除策略(Redis过期删除策略)的原理解释

评论 抢沙发

评论前必须登录!