Redis核心技术-高频问题-缓存淘汰策略

本文详细介绍了Redis的内存淘汰策略,包括noeviction、volatile和allkeys系列策略,以及LRU和LFU的区别。在实际生产环境中,作者选择了volatile-lru策略,因为它能减少淘汰key数据量且避免了LFU的额外统计开销。Redis的LRU并非完整实现,而是通过采样进行近似算法。LFU在Redis4.0后引入,解决了LRU的不精确性,通过访问频率和时间进行淘汰。
摘要由CSDN通过智能技术生成

  计算机内存不是无限大的,都有用完的时候,当内存满时,便触发Redis淘汰策略。

淘汰策略

  淘汰策略总共8种。

不进行数据淘汰的策略

  noeviction,默认使用的配置。

  noeviction策略是缓存被写满了,再有写请求来时,Redis 不再提供服务,而是直接返回错误。

仅淘汰配置过期时间key

  volatile-randomvolatile-ttlvolatile-lruvolatile-lfu(Redis 4.0 后新增)。

  volatile-ttl: 根据过期时间的先后进行删除,越早过期的越先被删除。
  volatile-random:在设置了过期时间的键值对中,进行随机删除。
  volatile-lru:会使用 LRU 算法(最近最少使用)筛选设置了过期时间的键值对。
  volatile-lfu :会使用 LFU 算法(最不经常使用)选择设置了过期时间的键值对。

淘汰所有缓存类型的key

  allkeys-lruallkeys-randomallkeys-lfu(Redis 4.0 后新增)三种。

  allkeys-random 策略,从所有键值对中随机选择并删除数据;
  allkeys-lru 策略,使用 LRU 算法(最近最少使用)在所有数据中进行筛选。
  allkeys-lfu 策略,使用 LFU 算法(最不经常使用)在所有数据中进行筛选。

lru和lfu对比

  如果我们的服务中有冷热数据隔离需求,lru无疑是一个比较好的办法。可以将缓存的一些不经常使用的冷数据,而且数据size比较大的,筛选出来清理掉。而近期频繁被使用的key就被保留下来了。

   常见的场景如下:

  • 电商平台的冷热数据:某个爆款的商品、秒杀商品热点信息可以保留下来。
  • 外卖平台:每天的11-13点,17-19点,一定是美食外卖品种的高频率访问时间段,而日用品、果蔬生鲜 大都会避开这个高峰期,这时如果内存不够用了,那么就会成为被优先删除的缓存类型。

  LRU算法的不足之处在于,一个本身很少被访问的key,只是刚刚被访问了1次,就被认为是最近有使用的热点数据,导致短时间内不会被淘汰。

  而LFU弥补了这个不足,LFU(Least Frequently Used)淘汰策略会根据key的最近访问频率进行淘汰,解决上面说的这个不足。

  • LFU在LRU的基础上,为每个数据增加了一个计数器,用于统计该数据的访问次数。
  • 当使用LFU策略淘汰数据时,会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出内存。
  • 如果两个缓存数据的访问次数相同,LFU再比较这两个key最近一次的访问时间,把访问时间更早的缓存key淘汰出内存。

我们电商项目生产环境使用volatile-lru淘汰方式,因为Redis定义为只是缓存数据,如果Redis不存在数据通过其他数据源(MySQL、Es等)提供并写入Redis,使用volatile-lru可以减少淘汰key数据量(实际应用中可能不设置过期时间可以很少)、避免了lfu额外统计数据的开销。
在这里插入图片描述

什么时候触发淘汰策略?

在Redis Memory占用超过我们配置的阈值的时候触发策略执行。
设置最大内存:

# redis.conf 配置最大内存空间占用为2gb,超过则执行内存淘汰策略
redis > CONFIG SET maxmemory 2gb

查询最大内存:

> config get maxmemory
maxmemory
536870912

淘汰算法

LRU算法

  LRU是Least Recently Used的缩写,按照最近最少使用的原则来筛选数据,最不常用的数据会被筛选出来,而最近频繁使用的数据会留在缓存中。

  LRU算法需要一个双向链表来记录数据的最近被访问顺序,但是出于节省内存的考虑,Redis的LRU算法并非完整的实现。

  Redis并不会选择最久未被访问的键进行回收,相反它会尝试运行一个近似LRU的算法,通过对少量键进行取样,然后回收其中的最久未被访问的键。通过调整每次回收时的采样数量maxmemory-samples,可以实现调整算法的精度。

  Redis Object的lru属性(Redis核心技术-数据结构3-String、Redis Object),以秒为单位存储了对象新建或者更新时的unix time,也就是LRU clock。

LFU

  LFU(least frequently used (LFU) page-replacement algorithm)。即最不经常使用页置换算法,要求在页置换时置换引用计数最小的页,因为经常使用的页应该有一个较大的引用次数。

  LFU是在Redis4.0后出现的,LRU的最近最少使用实际上并不精确,考虑下面的情况,如果在|处删除,那么A距离的时间最久,但实际上A的使用频率要比B频繁,所以合理的淘汰策略应该是淘汰B。LFU就是为应对这种情况而生的。

A~~A~~A~~A~~A~~A~~A~~A~~A~~A~~~|
B~~~~~B~~~~~B~~~~~B~~~~~~~~~~~B|

  LFU把原来的key对象的内部时钟的24位分成两部分,前16位还代表时钟,后8位代表一个计数器。16位的情况下如果还按照秒为单位就会导致不够用,所以一般这里以时钟为单位。而后8位表示当前key对象的访问频率,8位只能代表255,但是redis并没有采用线性上升的方式,而是通过一个复杂的公式,通过配置两个参数来调整数据的递增速度。

淘汰策略配置

  redis.conf配置:

# 淘汰策略,默认:noeviction
# maxmemory-policy noeviction

# LRU、LFU 和最小 TTL 算法不是精确算法而是近似算法
# 算法(为了节省内存),所以你可以调整它的速度或
# 准确性。 默认情况下,Redis 将检查五个键并选择一个
# maxmemory-samples 5

总结

一张图总结
在这里插入图片描述

参考:
https://www.jianshu.com/p/c8aeb3eee6bc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冲上云霄的Jayden

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值