2015
05-12

剖析Redis过期key的删除策略

最近在阅读《Redis设计与实现》这本书,书中关于Redis的实现原理,做了相对详细的介绍与说明。
Marser整理了Redis中对于过期key的几种删除策略。下面Marser来带你装逼带你飞,带你熬翔到天黑。

Redis中过期key的删除策略,分为三种:定时删除、定期删除、惰性删除。
其中,定时删除和定期删除是主动删除策略,惰性删除是被动删除策略。
下面就来逐一介绍这三种删除策略的原理及其优缺点。

1、定时删除

定时删除是在设置key的过期时间的同时,会创建一个定时器(timer)。定时器在key的过期时间来临时,立即执行对key的删除操作。
此种删除策略可以保证过期key会尽可能快的被删除,并释放过期key所占用的内存。
但是此种策略对CPU时间是最不友好的。在过期key比较多的情况下,删除过期key这一行为可能会占用相当一部分CPU时间,在内存不紧张但是CPU时间非常紧张的情况下,将CPU时间用在删除和当前任务无关的过期key上,无疑会对服务器的响应时间和吞吐量造成影响。
例如,正有大量的命令请求在等待服务器处理,并且服务器当前不缺少内存的情况下,服务器应当优先将CPU时间用在处理客户端的命令请求上面,而不是用在删除过期key上面。
并且创建一个定时器(timer)需要用到Redis服务器中的时间事件,而当前时间事件是用无序链表实现的,查找一个事件的时间复杂度为O(N),并不能高效地处理大量时间事件。要让服务器创建大量的定时器,从而实现定时删除,在现阶段来说并不现实。


2、定期删除

定期删除是每隔一段时间,程序就会对Redis数据进行一次检查,删除里面的过期key,至于要删除多少过期key,以及要检查多少个db,则是由Redis内部算法决定,没有去考证,如有盆友知情,欢迎告知。谢谢~~
Redis内部每隔一段时间执行一次删除过期key的操作,并通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响。但是限制删除操作执行的时长和频率需要合理地设置,否则可能会演变成定时删除或者惰性删除。
通过定期删除策略,可以有效地减少因为过期key而带来的内存浪费。

3、惰性删除

惰性删除是定时删除和定期删除的折中处理方案。它放任key过期不管,但是每次获取key时,都会检查取得的key是否过期,如果过期,则删除该key;若没有过期,就返回该key的值。
此策略对CPU时间来说是最友好的,只在取出key时,才对key进行过期检查,即只会在非做不可的情况下进行,并且删除的目标仅限于当前处理的key,不会在删除其他无关的过期key上花费任何CPU时间。
此策略的缺点是对内存是最不友好的。如果一个key已经过期,而这个key又仍然保留在db中,那么只要这个过期key不被删除,它所占用的内存就不会释放。例如,如果db中有非常多的过期key,而这些过期key又恰好没有被访问到的话,那它们也许永远也不会被删除,除非用户手动执行flushdb命令清空,这样会导致大量的无用的脏数据占用大量的内存。



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

「真诚赞赏,手留余香」
您的支持将鼓励我继续创作 :)