Redis源码剖析——内存淘汰策略

一、内存淘汰策略

设置了maxmemory的选项,redis内存使用达到上限。Redis中提供了一种内存淘汰策略,当内存不足时,Redis会根据相应的淘汰规则对key数据进行淘汰。Redis一共提供了8种淘汰策略,默认的策略为noeviction,当内存使用达到阈值的时候,所有引起申请内存的命令会都会报错。

  • volatile-lru,针对设置了过期时间的key,使用lru算法进行淘汰。
  • allkeys-lru,针对所有key使用lru算法进行淘汰。
  • volatile-lfu,针对设置了过期时间的key,使用lfu算法进行淘汰。
  • allkeys-lfu,针对所有key使用lfu算法进行淘汰。
  • volatile-random,从所有设置了过期时间的key中使用随机淘汰的方式进行淘汰。
  • allkeys-random,针对所有的key使用随机淘汰机制进行淘汰。
  • volatile-ttl,针对设置了过期时间的key,越早过期的越先被淘汰。
  • noeviction,不会淘汰任何数据,当使用的内存空间超过 maxmemory 值时,再有写请求来时返回错误。

前缀为volatile-和allkeys-的区别在于二者选择要清除的键时的字典不同,volatile-前缀的策略代表从redisDb中的expire字典中选择键进行清除;allkeys-开头的策略代表从dict字典中选择键进行清除。
内存淘汰算法的具体工作原理是:

  1. 客户端执行一条新命令,导致数据库需要增加数据(比如set key value)
  2. Redis会检查内存使用情况,如果内存使用超过 maxmemory,就会按照内存淘汰策略删除一些 key
  3. 新的命令执行成功

二、LUR

1.LRU算法

LRU是Least Recently Used的缩写,也就是表示最近很少使用,也可以理解成最久没有使用。也就是说当内存不够的时候,每次添加一条数据,都需要抛弃一条最久时间没有使用的旧数据。标准的LRU算法为了降低查找和删除元素的时间复杂度,一般采用Hash表和双向链表结合的数据结构,hash表可以赋予链表快速查找到某个key是否存在链表中,同时链表负责快速删除、添加节点

当新数据插入到链表头部时有两种情况。

  • 链表满了,把链表尾部的数据丢弃掉,新加入的缓存直接加入到链表头中。
  • 当链表中的某个缓存被命中时,直接把数据移到链表头部,原本在头节点的缓存就向链表尾部移动

2.redis中的LRU算法

  • Redis中维护一个大小为16的候选池,当第一次随机选取采用数据时,会把数据放入到候选池中,并且候选池中的数据会根据key的空闲时间进行排序。
  • 当第二次以后选取数据时,只有大于候选池内最小空闲时间的key才会被放进候选池。
  • 当候选池的数据满了之后,那么空闲时间最大的key就会被挤出候选池。当执行淘汰时,直接从候选池中选取空闲时间最大的key进行淘汰。

这样做的目的是能够选出最真实的最少被访问的key,能够正确选择不常使用的key。但LRU算法有一个弊端,假如一个key值访问频率很低,但是最近一次被访问到了,那LRU会认为它是热点数据,不会被淘汰。同样,经常被访问的数据,最近一段时间没有被访问,这样会导致这些数据被淘汰掉,导致误判而淘汰掉热点数据,于是在Redis 4.0中,新加了一种LFU算法。

二、LFU

LFU(Least Frequently Used),表示最近最少使用,它和key的使用次数有关,其思想是:根据key最近被访问的频率进行淘汰,比较少访问的key优先淘汰,反之则保留。LFU的原理是使用计数器来对key进行排序,每次key被访问时,计数器会增大,当计数器越大,意味着当前key的访问越频繁,也就是意味着它是热点数据。 它很好的解决了LRU算法的缺陷:一个很久没有被访问的key,偶尔被访问一次,导致被误认为是热点数据的问题。

LFU的实现原理如下图所示,LFU维护了两个链表,横向组成的链表用来存储访问频率,每个访问频率的节点下存储另外一个具有相同访问频率的缓存数据。具体的工作原理是:

  • 当添加元素时,找到相同访问频次的节点,然后添加到该节点的数据链表的头部。如果该数据链表满了,则移除链表尾部的节点
  • 当获取元素或者修改元素时,都会增加对应key的访问频次,并把当前节点移动到下一个频次节点

添加元素时,访问频率默认为1,随着访问次数的增加,频率不断递增。而当前被访问的元素也会随着频率增加进行移动。

 参考博客Redis内存淘汰策略_紫乾2014的博客-CSDN博客

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值