Redis过期策略和内存淘汰机制

Redis过期策略和内存淘汰机制

Redis的过期策略

我们在新增 Redis 缓存时可以设置缓存的过期时间,该时间保证了数据在规定的时间内失效,可以借助这个特性来实现很多功能。对于已经过期的数据,Redis 将使用两种策略来删除这些过期键,它们分别是惰性删除和定期删除。

惰性删除

惰性删除是指 Redis 服务器不主动删除过期的键值,而是当访问键值时,再检查当前的键值是否过期,如果过期则执行删除并返回 null 给客户端;如果没过期则正常返回值信息给客户端。
优点是不会浪费太多的系统资源,只是在每次访问时才检查键值是否过期。
缺点是删除过期键不及时,造成了一定的空间浪费。

定期删除

定期删除是指 Redis 服务器每隔一段时间会检查一下数据库,看看是否有过期键可以被清除。默认情况下 Redis 定期检查的频率是每秒扫描 10 次,用于定期清除过期键。当然此值还可以通过配置文件进行设置,在 redis.conf 中修改配置“hz”即可,默认的值为“hz 10”。

Redis内存淘汰策略

当 Redis 的内存超过最大允许的内存之后,Redis 会触发内存淘汰策略,这和过期策略是完全不同的两个概念,经常有人把二者搞混,这两者一个是在正常情况下清除过期键,一个是在非正常情况下为了保证 Redis 顺利运行的保护策略。

内存淘汰策略的区分

(1)noeviction:不淘汰任何数据,当内存不足时,执行缓存新增操作会报错,它是 Redis 默认内存淘汰策略。
(2)allkeys-lru:淘汰整个键值中最久未使用的键值。
(3)allkeys-random:随机淘汰任意键值。
(4)volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值。
(5)volatile-random:随机淘汰设置了过期时间的任意键值。
(6)volatile-ttl:优先淘汰更早过期的键值。
(7)volatile-lfu,淘汰所有设置了过期时间的键值中最少使用的键值;
(8)allkeys-lfu,淘汰整个键值中最少使用的键值。

Redis中有哪些内存淘汰算法?

存淘汰算法主要包含两种:LRU 淘汰算法和 LFU 淘汰算法。

LRU( Least Recently Used,最近最少使用)

LRU淘汰算法:是一种常用的页面置换算法,也就是说最久没有使用的缓存将会被淘汰。
LRU 是基于链表结构实现的,链表中的元素按照操作顺序从前往后排列,最新操作的键会被移动到表头,当需要进行内存淘汰时,只需要删除链表尾部的元素即可。
Redis 使用的是一种近似 LRU 算法,目的是为了更好的节约内存,它的实现方式是给现有的数据结构添加一个额外的字段,用于记录此键值的最后一次访问时间。Redis 内存淘汰时,会使用随机采样的方式来淘汰数据,它是随机取 5 个值 (此值可配置) ,然后淘汰最久没有使用的数据。

数据结构:

Redis过期策略和内存淘汰机制_第1张图片
Redis过期策略和内存淘汰机制_第2张图片

LFU(Least Frequently Used,最不常用的)

LFU淘汰算法:最不常用的算法是根据总访问次数来淘汰数据的,它的核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。
LFU 相对来说比 LRU 更“智能”,因为它解决了使用频率很低的缓存,只是最近被访问了一次就不会被删除的问题。如果是使用 LRU 类似这种情况数据是不会被删除的,而使用 LFU 的话,这个数据就会被删除。Redis 内存淘汰策略使用了 LFU 和近 LRU 的淘汰算法,具体使用哪种淘汰算法,要看服务器是如何设置内存淘汰策略的,也就是要看“maxmemory-policy”的值是如何设置的。

数据结构:
  • LFU主要使用了两个双向链表去形成一个二维的双向链表,一个用来保存访问频率,另一个用来访问频率相同的所有元素,其内部按照访问时间排序。
  • 当添加元素的时候访问频次默认为1,于是找到相同频次的节点,然后添加到相同频率节点对应的双向链表的头部,
  • 当元素被访问的时候就会增加对应key的访问频率,并且把访问的节点移动到下一个频次的节点。
  • Redis过期策略和内存淘汰机制_第3张图片

两者的区别?

  • 过期策略是在正常情况下清除过期键;
  • 内存淘汰策略是在非正常情况下为了保证 Redis 顺利运行的保护策略。

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