Redis过时键删除策略

三种删除策略:算法

  1. 定时删除:在设置键的过时时间的同时,建立一个定时器(timer),让定时器在键的过时时间来临时,当即执行对键的删除操做。数据库

  2. 惰性删除:听任键过时无论,可是每次从键空间中获取键时,都检查取得的键是否过时,若是过时的话,就删除该键;若是没有过时,就返回该键。服务器

  3. 按期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过时键。至于要删除多少过时键,以及要检查多少个数据库,则由算法决定。spa

在这三种策略中,第一种和第三种为主动删除策略,而第二种则为被动删除策略。日志

  定时删除策略是对内存最友好的:经过使用定时器,定时删除策略能够保证过时键会尽量快地被删除,并释放过时键所占用的内存。另外一方面,定时删除策略的缺点是,它对CPU时间是最不友好的:在过时键比较多的状况下,删除过时键这一行为可能会占用至关一部分CPU时间,在内存不紧张可是CPU时间很是紧张的状况下,将CPU时间用在删除和当前任务无关的过时键上,无疑会对服务器的响应时间和吞吐量形成影响。orm

  例如,若是正有大量的命令请求在等待服务器处理,而且服务器当前不缺乏内存,那么服务器应该优先将CPU时间用在处理客户端的命令请求上面,而不是用在删除过时键上面。事件

  除此以外,建立一个定时器须要用到Redis服务器中的时间事件,而当前时间事件的实现方式--无序链表,查找一个事件的时间复杂度为O(N) ---- 并不能高效地处理大量时间事件。内存

  所以,要让服务器建立大量的定时器,从而实现定时删除策略,在现阶段来讲并不现实。ci


  惰性删除策略对CPU时间来讲是最友好的:程序只会在取出键时才对键进行过时检查,这能够保证删除过时键的操做只会在非作不可的状况下进行,而且删除的目标仅限于当前处理的键,这个策略不会在删除其余无关的过时键上花费任何CPU时间。it

  惰性删除策略的缺点是,它对内存是最不友好的:若是一个键已通过期,而这个键又仍然保留在数据库中,那么只要这个过时键不被删除,它所占的内存就不会释放。

  在使用惰性删除策略时,若是数据库中有很是多的过时键,而这些过时键又刚好没有被访问到的话,那么它们也许永远也不会被删除(除非用户手动执行FLUSHDB),咱们甚至能够将这种状况看做是一种内存泄露----无用的垃圾数据占用了大量的内存,而服务器却不会本身去释放它们,这对于运行状态很是依赖于内存的Redis服务器来讲,确定不是一个好消息。

  举个例子,对于一些和时间有关的数据,好比日志(log),在某个时间以后,对它们的访问就会大大减小,甚至再也不访问,若是这类过时数据大量地积压在数据库中,用户觉得服务器已经自动将它们删除了,但实际上这些键仍然存在,并且键所占用的内存也没有释放,那么形成的后果确定是很是严重的。


  从上面对定时删除和惰性删除的讨论来看,这两种删除方式在单一使用都有明显的缺陷:

    1. 定时删除占用太多CPU时间,影响服务器的响应时间和吞吐量;

    2. 惰性删除浪费太多内存,有内存泄露的危险。

  按期删除策略是前两种策略的一种整合和折中:

    1. 按期删除策略每隔一段时间执行一次删除过时键操做,并经过限制删除操做执行的时长和频率来减小删除操做对CPU时间的影响;

    2. 除此以外,经过按期删除过时键,按期删除策略有效地减小了由于过时键而带来的内存浪费。

  按期删除策略的难点是肯定删除操做执行的时长和频率:

    1. 若是删除操做执行的太频繁,或者执行的时间太长,按期删除策略就会退化成定时删除策略,以致于将CPU时间过多地消耗在删除过时键上面。

    2. 若是删除操做执行得太少,或者执行的时间过短,按期删除策略又会和惰性删除策略同样,出现浪费内存的状况。

  所以,若是采用按期删除策略的话,服务器必须根据状况,合理地设置删除操做的执行时长和执行频率。

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

相关文章
相关标签/搜索