redis过期key的清理/删除策略以及淘汰机制(淘汰策略)

一、简述

Redis 中过期 key 的删除策略,分为三种:定时删除、定期删除、惰性删除。其中,定时删除和定期删除是主动删除策略,惰性删除是被动删除策略。删除策略:是当数据到期,redis对过期数据的处理策略。淘汰策略:是当数据放不下的时候,淘汰其他数据的策略。

二、定时删除

定时删除是在设置 key 的过期时间的同时,会创建一个定时器(timer)。定时器在 key 的过期时间来临时,立即执行对 key 的删除操作。

1️⃣优点:
保证过期 key 会尽可能快的被删除,并释放过期 key 所占用的内存。

2️⃣缺点:
对 CPU 时间最不友好。在过期 key 比较多的情况下,删除过期 key 这一行为可能会占用相当一部分 CPU 时间,在内存不紧张但是 CPU 时间非常紧张的情况下,将 CPU 时间用在删除和当前任务无关的过期 key 上,无疑会对服务器的响应时间和吞吐量造成影响。

创建一个定时器(timer)需要用到 Redis 服务器中的时间事件,而当前时间事件是用无序链表实现的,查找一个事件的时间复杂度为 O(N),并不能高效地处理大量时间事件。要让服务器创建大量的定时器,从而实现定时删除,在现阶段来说并不现实。

三、定期删除

定期删除是每隔一段时间,程序就会对 Redis 数据进行一次检查,删除里面的过期 key,至于要删除多少过期 key,以及要检查多少个 db,则是由 Redis 内部算法决定。
Redis 通过限制删除操作执行的时长和频率来减少对 CPU 时间的影响。限制删除操作执行的时长和频率需要合理地设置,否则可能会演变成定时删除或者惰性删除。

1️⃣优点:
通过定期删除策略,可以有效地减少因为过期 key 而带来的内存浪费。

四、惰性删除

惰性删除是定时删除和定期删除的折中处理方案。它放任 key 过期不管,但是每次获取 key 时,都会检查取得的 key 是否过期,如果过期,则删除该 key;若没有过期,就返回该 key 的值。

1️⃣优点:
对 CPU 时间最友好。只在取出 key 时,才对 key 进行过期检查,即只会在非做不可的情况下进行,并且删除的目标仅限于当前处理的 key,不会在删除其他无关的过期 key 上花费任何 CPU 时间。

2️⃣缺点:
对内存最不友好。如果一个 key 已经过期,而这个 key 又仍然保留在 db 中,那么只要这个过期 key 不被删除,它所占用的内存就不会释放。如果 db 中有大量的过期 key,而这些过期 key 又恰好没有被访问到的话,那它们也许永远也不会被删除,除非用户手动执行 flushdb 命令清空,这样会导致大量的无用的脏数据占用大量的内存。

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

五,Redis内存淘汰机制

redis内存淘汰机制

noeviction:内存不足以写入新数据的时候会直接报错。
allKeys-lru:内存不足以写入新数据时候,移除最近最少使用的key。
allKeys-random: 内存不足以写入新数据时,随机移除key。
volatile-lru: 内存不足以写入新数据时,在设置了过期时间的key当中移除最近最少使用的key。
volatile-random: 内存不足以写入新数据时,在设置了过期时间的key中,随即移除key。
volatile-ttl: 内存不足以写入新数据时,在设置了过期时间的key当中移除最先过期的key。
allkeys-lfu:就是从所有的key中挑选使用频率最低的key,进行淘汰。(这是Redis 4.0版本后新增的策略)
volatile-lfu 从过期时间的结果集中选择使用频率最低的key开始删除(这是Redis 4.0版本后新增的策略)

上面八种你可以这么记:
不移除直接报错: noeviction。
在所有key中移除: ①.allKeys-lru ②. allKeys-random ③ allkeys-lfu
在设置了过期时间的key中移除: ①. volatile-lru ②. volatile-random ③.volatile-ttl 4、volatile-lfu
一般常用allKeys-lru
解释
LRU算法的设计原则是如果一个数据近期没有被访问到,那么之后一段时间都不会被访问到。所以当元素个数达到限制的值时,优先移除距离上次使用时间最久的元素。
可以使用双向链表Node+HashMap来实现,每次访问元素后,将元素移动到链表头部,当元素满了时,将链表尾部的元素移除,HashMap主要用于根据key获得Node以及添加时判断节点是否已存在和删除时快速找到节点。

LFU算法的设计原则是如果一个数据在最近一段时间被访问的时次数越多,那么之后被访问的概率会越大,基本实现是每个数据都有一个引用计数,每次数据被访问后,引用计数加1,需要淘汰数据时,淘汰引用计数最小的数据。在Redis的实现中,每次key被访问后,引用计数是加一个介于0到1之间的数p,并且访问越频繁p值越大,而且在一定的时间间隔内,
如果key没有被访问,引用计数会减少。

你可能感兴趣的:(redis,redis,缓存)