Redis 缓存回收的7种策略volatile设置过期时间及allkeys所有数据范围内

1、基础说明

当redis设置内存使用限制后,当达到内存限制时,Redis将尝试删除key(控制节点的最大使用内存)

redis.conf中配置项maxmemory <bytes>或者控制台执行CONFIG SET maxmemory 4gb,设置内存
在这里插入图片描述
参数说明:

  • maxmemory的默认值是0,也就是不限制内存的使用。
  • 32bit系统如果使用默认配置或配置为maxmemory 0则最大使用3G内存。
  • maxmemory的值没有最小限制(但是如果低于1MB,会打一条WARNING日志)。
  • 如果设置了maxmemory选项(值 >= 1),redis在接收命令时总是会判断当前是否已经超出最大内存限制,如果超过限制会根据驱逐策略去释放内存(如果是同步释放且释放内存很大,则会阻塞其他命令的执行)。
  • 单位,默认字节B,支持,KB、MB、GB、K(1000B)、M(1000000B)、G(1000000000B)

推荐设置方案(需要结合应用数据实际访问特征成本开销来综合考虑的。)

  • 根据“八二原理”,最常被访问的 20% 的数据来说,它们贡献的访问量,既有可能超过 80%,也有可能不到 80%。建议把缓存容量设置为总数据量的 15% 到 30%,兼顾访问性能和内存空间开销。

2、淘汰策略

缓存被写满是不可避免的。一共有7种淘汰策略,1种拒绝策略:

  • 针对设置过期时间的键值对:即使缓存没有写满,这些数据如果过期了,也会被删除。
    除。当然,如果它的过期时间到了但未被策略选中,同样也会被删除。
    • volatile-random:从设置了过期时间的键值对中,进行随机删除
    • volatile-ttl:从设置了过期时间的键值对中,根据过期时间的先后进行删除,越早过期的越先被删除
    • volatile-lru:从设置了过期时间的键值对中,使用LRU算法筛选,
    • volatile-lfu:从设置了过期时间的键值对中,使用LFU算法筛选,在 LRU算法的基础上,同时考虑了数据的访问时效性和数据的访问次数
  • 所有键值对
    • allkeys-random:从所有键值对中,随机选择并删除数据;
    • allkeys-lru:从所有键值对中,使用LRU算法筛选,
    • allkeys-lfu:从所有键值对中,使用LFU算法筛选,
  • noevction:不进行数据淘汰。一旦缓存被写满了,再有写请求来时,Redis不再提供服务,而是直接返回错误

如果一个键值对被删除策略选中了,即使它的过期时间还没到,也需要被删。

设置过期key的方式EXPIRE、PEXPIRE、EXPIREAT、PEXPIREAT

  • 剩余时间
    • EXPIRE(秒级)、PEXPIRE(毫秒级)
  • 指定过期时间戳
    • EXPIREAT(设置秒级)、PEXPIREAT(设置毫秒级)

2.1、LRU算法:最近最少使用的原则

LRU 算法的全称是 Least Recently Used,按照最近最少使用的原则来筛选数据,最不常用的数据会被筛选出来,而最近频繁使用的数据会留在缓存中。维护一个链表,链表头是MRL(最常使用的数据),链表尾就是LRU(最不常使用的数据)。LRU需要用链表管理所有的缓存数据,这会带来额外的空间开
销,当有数据被访问时,需要在链表上把该数据移动到 MRU 端,如果有大量数据被访问,就会带来很多链表移动操作,会很耗时

Redis 中,LRU算法被做了简化,以减轻数据淘汰对缓存性能的影响。Redis 默认会记录每个数据的最近一次访问的时间戳(由键值对数据结构RedisObject 中的 lru 字段记录)。

  1. Redis在决定淘汰的数据时,第一次会随机选出N 个数据,把它们作为一个候选集合。
  2. Redis 会比较这 N 个数据的 lru 字段,把lru 字段值最小的数据从缓存中淘汰出去。
  3. 当需要再次淘汰数据时,Redis 需要挑选数据进入第一次淘汰时创建的候选集合。挑选标准是:
    1. 能进入候选集合的数据的 lru 字段值必须小于候选集合中最小的 lru 值。
    2. 有新数据进入候选数据集后,如果候选数据集中的数据个数达到了 maxmemory-samples,Redis 就把候选数据集中 lru 字段值最小的数据淘汰出去。

Redis 提供了一个配置参数 maxmemory-samples,这个参数就是 Redis 选出的数据个数N。例如,执行如下命令,可以让 Redis 选出 100 个数据作为候选数据集:

CONFIG SET maxmemory-samples 100

2.2、LFU算法

LFU 策略中会从两个维度来筛选并淘汰数据:

  • 一是,数据访问的时效性(访问时间离当前时间的远近);
  • 二是,数据的被访问次数。

LFU 缓存策略是在 LRU 策略基础上,为每个数据增加了一个计数器,来统计这个数据的访问次数。当使用 LFU 策略筛选淘汰数据时:

  • 首先会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出缓存。
  • 如果两个数据的访问次数相同,LFU 策略再比较这两个数据的访问时效性,把距离上一次访问时间更久的数据淘汰出缓存。
  • 如果一个key的计数器值特别大,但是长时间没有被访问,redis中LFU算法会有对应的衰减机制
    • lfu_log_factor衰减因子:控制计数器值增加的速度,避免 counter(8bit) 值很快就到 255 了。
    • lfu_decay_time默认1:如果数据在 N 分钟内没有被访问,那么它的访问次数就要减 N。
      在这里插入图片描述
      LRU 策略更加关注数据的时效性,而 LFU 策略更加关注数据的访问频次。

3、淘汰策略使用

  1. 优先使用 allkeys-lru 策略。可以充分利用 LRU 这一经典缓存算法的优势,把最近最常访问的数据留在缓存中,提升应用的访问性能。如果业务数据中有明显的冷热数据区分,建议使用allkeys-lru策略。
  2. 如果业务应用中的数据访问频率相差不大,没有明显的冷热数据区分,建议使用allkeys-random策略,随机选择淘汰的数据就行。
  3. 如果业务中有置顶的需求,比如置顶新闻、置顶视频,那么,可以使用volatile-lru策略,同时不给这些置顶数据设置过期时间。这样一来,这些需要置顶的数据一直不会被删除,而其他数据会在过期时根据 LRU规则进行筛选。

4、缓存污染

在一些场景下,有些数据被访问的次数非常少,甚至只会被访问一次。当这些数据服务完访问请求后,如果还继续留存在缓存中的话,就只会白白占用缓存空间。这种情况,就是缓存污染。

当缓存污染不严重时,只有少量数据占据缓存空间,此时,对缓存系统的影响不大。但是,缓存污染一旦变得严重后,就会有大量不再访问的数据滞留在缓存中。如果这时数据占满了缓存空间,我们再往缓存中写入新数据时,就需要先把这些数据逐步淘汰出缓存,这就会引入额外的操作时间开销,进而会影响应用的性能。

要解决缓存污染问题,最关键的技术点就是能识别出这些只访问一次或是访问次数很少的数据,在淘汰数据时,优先把它们筛选出来并淘汰掉。所以采用LFU策略

  • volatile-lfu
  • allkeys-lfu
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值