Redis的内存淘汰策略的学习记录

Redis采用惰性删除和定时删除策略管理过期键。惰性删除仅在访问键时检查是否过期,而定时删除通过周期性扫描进行主动清理。内存超出限制时,Redis提供多种内存淘汰策略,如volatile-lru、allkeys-lru等。并非使用真实LRU算法,而是近似实现,通过随机样本进行淘汰。
摘要由CSDN通过智能技术生成

Redis的过期键淘汰策略


由于Redis是内存数据库,为了更加方便的管理内存。Redis的每种数据类型都可以设置过期时间。那么Redis是如何管理过期的key的,目前主要有两种做法即:定时删除惰性删除

惰性删除


惰性删除,顾名思义是一种懒操作的过程。在程序设计当中,为了进一步提高程序的性能(这是为了只有在需要的时候才去分配资源进行操作,提高系统的资源利用率),使用了大量的惰性思想。

在Redis当中也不例外,由于我们知道Redis采用了单线程模型,只有一条工作线程。因此不能直接遍历所有key的集合进行删除。这样会阻塞线上的业务,造成读写延迟,非常不利于客户的体验(并且有可能会造成客户端的超时断开,而由于这个原因出现的问题不会被记录在slowlog当中,这是由于slowlog只会记录又逻辑问题导致的 慢操作)。

而惰性删除则在一定程度上解决了这个问题,只有在使用key的时候才去检查为key所设置的超时时间是否超过,如果该key已经过期,则进行删除,并且在aof文件当中记录一条del指令。

定时删除


惰性删除可以提高系统的利用率,但是也带来了一些弊端,即过期key无法即使得到删除,有可能会使无用的key长期占用系统的内存,导致Redis的内存占用率高但有效利用率却偏低。因此,Redis除了会使用惰性删除管理内存之外,还会使用定时删除策略来删除过期键。

Redis会将设置过期时间的Key单独存放在一个过期字典当中。并且默认每100ms会进行一次扫描删除的操作。这里扫面的过程并不是直接进行全集合扫描,而是采用了一种贪心的思想:

  1. 从过期字典当中抽取出20个key。
  2. 检查其过期时间。
  3. 如果淘汰的key超过1/4,则循环(1),(2)步。

为了避免极端情况,即同时有大量的key过期导致循环持续进行而导致线上业务的阻塞。redis设置了单次扫描的时间上限为25ms。 而在我们的线上业务当中,我们应该尽量避免大量key同时到期。一方面大量的key同时到期可能会造成缓存雪崩的情况进而打崩数据库而造成服务不可用;另一方面内存管理器频繁回收内存页也会占用一定的CPU时间,导致服务的吞吐量下降。


上述的惰性删除和定时删除都是Redis在正常情况下保证内存利用率的一种方式。而当Redis中存储的数据超出物理内存限制之后,内存当中的数据就会频繁的使用SWAP空间进行数据交换而这无疑会拉低Redis的性能。

因此,为了限制Redis的内存使用上线,Redis提供了配置参数Maxmemory来限制内存超出的期望大小。当实际内存超出了Maxmemory之后,则会使用以下几种内存淘汰策略进行内存回收。

  • noevction(使用这种方式会阻塞线上写服务而对读服务没有影响,并且保证了数据的正确性)
  • volatile-lru
  • volatile-random
  • volatile-ttl
  • allkeys-lru
  • allkeys-random

上述内存淘汰策略当中,使用volatile-XXX开头的回收目标是设置了过期时间的Key集合。而allkeys-XXX的回收目标则为所有的key,因为有可能会丢失数据。

而Redis为了保证简洁性和效率(无论是时间效率还是空间效率)都没有使用真实的LRU算法,而是使用了近似LRU算法。该算法的实现是为每个key都冗余存储了一个24bit的字段即最近使用时间。在使用上述内存淘汰策略的时候,随机采用Maxmemory_sample个样本进行淘汰,如果内存空间还是大于Maxmemory,则循环这一操作。此外Redis3.0之后引入了淘汰池可以缓存每一轮淘汰的剩余集合,以此来提高淘汰的效率和准确性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值