吃透Redis(八):缓存淘汰篇-LRU算法

Redis使用近似LRU算法来实现内存淘汰,避免了严格LRU带来的内存和性能开销。在内存达到maxmemory阈值时,Redis通过全局LRU时钟值和键值对的LRU信息判断数据时效性。算法在每个命令执行前检查是否需要淘汰数据,通过随机采样和空闲时间比较选择淘汰的键值对。这一过程是循环进行的,直到内存降至设定值以下。

一、概述

redis是内存数据库,当内存使用达到了一定阈值,就会触发缓存淘汰策略,这和 Redis 配置文件 redis.conf 中的两个配置参数有关:

  • maxmemory,该配置项设定了 Redis server 可以使用的最大内存容量,一旦 server 使用的实际内存量超出该阈值时,server 就会根据 maxmemory-policy 配置项定义的策略,执行内存淘汰操作;
  • maxmemory-policy,该配置项设定了 Redis server 的内存淘汰策略,主要包括近似 LRU 算法、LFU 算法、按 TTL 值淘汰和随机淘汰等几种算法。

maxmemory-policy 内存淘汰策略一共八种:

  1. noeviction:noeviction 策略是不会进行数据淘汰的。
  2. volatile-random:在设置了过期时间的 key 中随机淘汰掉。
  3. allkeys-random:在所有的 key 中随机淘汰掉。
  4. volatile-ttl:把设置了过期时间的 key 中剩余存活时间最短的筛选出来并淘汰掉。
  5. volatile-lru:从设置过期时间的key中挑选出 最近最少使用(LRU) 的数据淘汰。
  6. allkeys-lru:从所有的 key 中挑选出 最近最少使用(LRU) 的数据淘汰。
  7. volatile-lfu:从设置过期时间的key中挑选出 最近最少使用频率(LFU) 的数据淘汰。
  8. allkeys-lfu:从所有的 key 中挑选出 最近最少使用频率(LFU) 的数据淘汰。

二、LRU算法

1、普通LRU算法

LRU 算法就是指最近最少使用(Least Recently Used,LRU)算法,这是一个经典的缓存算法。

从基本原理上来说,LRU 算法会使用一个链表来维护缓存中每一个数据的访问情况,并根据数据的实时访问,调整数据在链表中的位置,然后通过数据在链表中的位置,来表示数据是最近刚访问的,还是已经有一段时间没有访问了。

LRU 算法的执行,可以分成三种情况来掌握:

  • 当有新数据插入时,LRU 算法会把该数据插入到链表头部,同时把原来链表头部的数据及其之后的数据,都向尾部移动一位。
  • 当有数据刚被访问了一次之后,LRU 算法就会把该数据从它在链表中的当前位置,移动到链表头部。同时,把从链表头部到它当前位置的其他数据,都向尾部移动一位。
  • 当链表长度无法再容纳更多数据时,若再有新数据插入,LRU 算法就会去除链表尾部的数据,这也相当于将数据从缓存中淘汰掉。

所以我们可以发现,如果要严格按照 LRU 算法的基本原理来实现的话,我们需要在代码中实现如下内容:

  • 要为 Redis 使用最大内存时,可容纳的所有数据维护一个链表;
  • 每当有新数据插入或是现有数据被再次访问时,需要执行多次链表操作。

而假设 Redis 保存的数据比较多的话,那么,这两部分的代码实现,就既需要额外的内存空间来保存链表,还会在访问数据的过程中,让 Redis 受到数据移动和链表操作的开销影响,从而就会降低 Redis 访问性能

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃透Java

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值