面试: Redis的淘汰策略

发布于:2022-12-29 ⋅ 阅读:(328) ⋅ 点赞:(0)

Redis中共有八种内存淘汰策略:

  1. Volatile-lru: 设置了过期时间的Key使用了LRU算法淘汰;
  2. Allkeys-lru: 所有key使用LRU算法;
  3. Volatile-lfu: 设置了过期时间的key使用了LFU算法淘汰;
  4. Allkeys-lfu: 所有key使用了LFU算法淘汰;
  5. Volatile-random: 设置了过期时间的key使用随机淘汰;
  6. Allkeys-random: 所有key使用随机淘汰;
  7. Volatile-ttl: 设置了过期时间的key根据过期时间淘汰,越早过期越早淘汰;
  8. Noeviction: 默认策略,当内存达到设置的最大值时,所有申请内存的操作都会报错,(如set,ipush等),只读操作如get命令可以正常执行.

LRU、LFU和volatile-ttl都是近似随机算法;

在缓存的内存淘汰策略中有FIFO、LRU、LFU三种,其中LRU和LFU是Redis在使用的.

FIFO是最简单的淘汰策略,遵循先进先出的原则.

LRU算法:表示最近最少使用,该算法根据数据的历史记录来进行淘汰数据,其核心思想是”最近被使用过,那么将来被访问的记录也更高”.

LRU算法的常见实现方式为链表,新数据放在链表头,链表中的数据被访问就移动到链头,链表满的时候从链表尾部移除数据.

而Redis中使用的是近似LRU算法,为什么说是近似呢?Redis中是随机采样5个Key,然后从中选择访问时间最早的Key进行淘汰,因此当采样Key的数量与Redis库中Key的数量越接近,淘汰的规则就越接近LRU算法.官方推荐采样5个Key就够了,最多不超过10个,越大就越消耗CPU的资源.

但在LRU算法下,Redis会为每个Key新增一个3字节的内存空间来存储Key的访问时间.

LFU算法表示最不经常使用,它是根据数据的历史访问频率来淘汰数据,其核心思想是”如果数据过去被访问多次,那么将来被访问的频率也更高”.

LFU算法反映了一个Key的热度情况,不会因LRU算法的偶尔一次被访问被误认为是热点数据.

LFU算法的常见实现方式为链表:新数据放在链表尾部,链表中的数据按照被访问次数降序排列,访问次数相同的按最近访问时间降序排列,链表满的时候从链表尾部移除数据.

过期删除策略

Redis内存没有被占满时,过期的Key是如何从内存中删除的.

在Redis中过期的Key不会立刻从内存中删除,而是会同时以下面两种策略进行删除

  1. 惰性删除: 当Key被访问时检查该Key的过期时间,若已过期则删除;已过期未被访问的数据仍保存在内存中,消耗内存资源;
  2. 定期删除: 每隔一段时间,随机检查设置了过期的Key并删除已过期的Key;维护定时器消耗CPU资源;

Redis每10s进行一次过期扫描:

  1. 随机取20个设置了过期策略的Key;
  2. 检查20个Key中过期时间中已过期的Key并删除;
  3. 如果有超过25%的Key已过期则重复第一步;

这种循环随机操作会持续到过期Key可能仅占全部的Key25%以下,并且为了保证不会出现循环过多的情况,默认扫描时间不会超过25ms;


网站公告

今日签到

点亮在社区的每一天
去签到