Redis 缓存淘汰策略
Redis 缓存淘汰策略
Redis 共支持八种淘汰策略,分别是noeviction、volatile-random、volatile-ttl、volatile-lru、volatile-lfu、allkeys-lru、allkeys-random和allkeys-lfu策略。
主要分为三类:
- 不淘汰:
- noeviction(v4.0后默认)
- 对设置了过期时间的数据中进行淘汰
- 随机:volatile-random
- ttl:volatile-ttl
- lru:volatile-lru
- lfu:volatile-lfu
- 全部数据进行淘汰
- 随机:allkeys-random
- lru:allkeys-lru
- lfu:allkeys-lfu
noeviction
该策略是 Redis 的默认策略。在这种策略下,一旦缓存被写满了,再有写请求来时,Redis 不再提供服务,而是直接返回错误。这种策略不会淘汰数据,所以无法解决缓存污染问题。一般生产环境下不建议使用。
volatile-random
这个算法比较简单,在设置了过期时间的键值对中,进行随机删除。因为是随机删除,无法把不再访问的数据筛选出来,所以可能依然会存在缓存污染现象,无法解决缓存污染问题。
volatile-ttl
这种算法判断淘汰数据时参考的指标比随机删除时多进行一步过期时间的排序。Redis 在筛选需删除的数据时,越早过期的数据越优先被选择。
volatile-lru
LRU算法:LRU算法的全称是 Least Recently Used,按照最近最少使用的原则来筛选数据。这种模式下会使用LRU算法筛选设置了过期时间的键值对。
Redis 优化的LRU算法实现:
Redis 会记录每个数据最近一次被访问的时间戳。在Redis在决定淘汰的数据时,第一次会随机选出 N 个数据,把它们作为一个候选集合。接下来,Redis 会比较这 N 个数据的 lru 字段,把 lru 字段值最小的数据从缓存中淘汰出去。通过 随机读取 待删除集合,可以让 Redis 不用维护一个巨大的链表,也不用操作链表,进而提升性能。
Redis 选出的数据个数 N,通过配置参数 maxmemory-samples 进行配置。个数 N 越大,则候选集合越大,选择到的最久未被使用的就更准确;N越小,选择到最久未被使用的数据的概率也会随之减小。
volatile-lfu
会使用 LFU 算法 选择设置了过期时间的键值对。
LFU算法:LRU 缓存策略试在LRU策略的基础上,为每个数据增加了一个计数器,来统计这个数据的访问次数。当使用 LFU 策略筛选淘汰数据时:
- 首先会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出缓存。
- 如果两个数据的访问次数相同,LFU 策略再比较这两个数据的访问时效性,把距离上次访问时间更久的数据淘汰出缓存。
Redis 的 LFU 算法实现:
当 LFU 策略筛选数据时,Redis 会在候选集合中,根据数据 lru字段的后 8bit 选择访问次数最少的数据进行淘汰。当访问次数相同时,再根据 lru 字段的前 16bit 值大小,选择访问时间最久远的数据进行淘汰。
Redis 只是用 8bit 记录数据的最大访问次数,而 8bit 记录的最大值是 255,这样在访问快速的情况下,如果每次被访问就将访问次数加1,很快某条数据就达到最大值 255,可能很多数据都是 255 ,那么就退化成 LRU 算法了。所以 Redis 为了解决这个问题,实现了一个更优的计数规则,并可以通过配置项,来控制计数器增加的速度。
参数:
lfu-log-factor:用计数器当前的值乘以配置项lfu_log_factor再加1,再取其倒数,得到一个 p 值;然后,把这个 p 值和 一个取值范围在(0,1)间的随机数 r 值比大小,只有 p 值大于 r 值时,计数器才加1。
lfu-decay-time:控制访问次数衰减。LFU 策略会计算当前时间和数据最近一次访问时间的差值,并把这个差值换算成以分钟为单位。然后,LRU 策略再把这个差值除以 lfu_decay_time值,所得到的结果就是数据 counter 要衰减的值。
lfu-log-factor ,设置越大,递增概率越低,lfu-decay-time设置越大,衰减速度会越慢。
我们在应用 LFU 策略时,一般可以将lfu_log_factor取值为 10 。如果业务应用中有短时间高频访问的数据的话,建议把 lfu_decay_time值设置为 1。可以快速衰减访问次数。
allkeys-lru
使用 LRU 算法在 所有数据 中进行筛选。具体的LFU算法跟上述 volatile-lru 中介绍的一致,只是筛选的数据范围是全部缓存。
allkeys-random
从所有键值对中随机选择并删除数据。volatile-random 跟 allkeys-random 算法一样,随机删除就无法解决缓存污染问题。
allkeys-lfu
使用 LFU 算法在所有数据中进行筛选。具体 LFU 算法跟上述 volatile-lfu 中介绍的一致,只是筛选的数据范围是全部缓存。

浙公网安备 33010602011771号