当前位置: 首页 > 科技观察

一文看懂Redis的内存回收策略和Key过期策略

时间:2023-03-13 01:27:26 科技观察

1。前言Redis作为目前最流行的Key-Value存储系统,在大大小小的系统中都扮演着重要的角色,无论是会话存储还是热点数据缓存,或者其他场景,我们都会用到Redis。在生产环境中,我们偶尔会遇到Redis服务器内存不足的情况。这种情况下如何回收Redis的内存呢?另外,有过期时间的RedisKey如何处理?2.Redis内存设置我们都知道,如果要设置Redis的最大内存大小,只需要在配置文件redis.conf中配置一行maxmemoryxxx即可,也可以动态配置Redis的内存大小,在运行时通过configset命令。3.Redis内存过期策略3.1.过期策略的配置所以当Redis内存不够用的时候,我们需要知道Redis采用什么策略来淘汰数据。在配置文件中,我们使用maxmemory-policy来配置策略,如下图:我们可以看出策略的取值如下:volatile-lru:使用LRU算法对所有数据进行淘汰有过期时间的密钥;alkeys-lru:使用最近最少使用的LRU算法,淘汰所有key中的数据,保证新增数据正常;volatile-random:随机淘汰所有有过期时间的key中的数据;allkeys-random:随机剔除所有key中的数据;volatile-ttl:在所有有过期时间的key中,剔除最早会过期的数据;noeviction:不回收,当达到最大内存时,添加新数据时会返回错误,不会清除旧数据。这是Redis的默认策略;volatile-lru,volatile-random,volatile-ttl的情况和Redis中没有过期Key时的noeviction策略是一样的。淘汰策略可动态调整,调整时无需重启。原文是这么说的,我们可以根据自己的Redis模式动态调整策略。“根据应用程序的访问模式选择正确的驱逐策略很重要,但是您可以在应用程序运行时在运行时重新配置策略,并使用RedisINFO输出监控缓存未命中和命中的次数,以便调整你的设置。》3.2.策略执行过程中,客户端运行添加数据申请内存的命令;Redis会检查内存使用情况,如果已经超过最大限制,则根据配置的内存淘汰,淘汰对应的key3.3.近似LRU算法Redis中的LRU算法不是精确LRU算法,而是采样LRU,我们可以通过设置maxmemory-samples5来设置采样大小在配置文件中,默认值为5,我们可以自己调整,官方采用的对比如下,我们可以看到当采用数设置为10时,已经非常接近真实的LRU算法了。在Redis3.x以上版本进行了优化。目前的近似LRU算法在效率上有了很大的提升。Redis之所以没有对实际的LRU算法进行采样,是因为它非常消耗内存。原文是这么说的Redis之所以没有使用真正的LRU实现,是因为它需要更多的内存。4.密钥过期策略4.1.给key设置过期时间Redis的内存回收策略前面介绍过。我们先来看一下Key的过期策略,说到Key的过期策略,当然是指带过期时间的key,如下:通过redis>setnameziyouuex100命令,我们设置一个key在Redis中以name为数据,值为ziyouu,从上面的截图中,我们可以看到右下角有一个TTL,并且每刷新一次就递减,说明我们设置成功了有过期时间的密钥。4.2Redis如何清除有过期时间的key对于如何清除过期的key,我们很自然地可以想到可以给每个key加上一个定时器,这样当时间到了过期时间,key就会被自动删除。这种策略称为时序策略。这种方式对内存友好,因为过期的可以及时清理,但是由于每个有过期时间的key都需要定时器,所以这种方式对CPU不友好,会占用大量CPU。另外,这种方法是一种主动行为。有主动的和被动的。代替定时器,我们可以在每次访问key的时候判断key是否到了过期时间,过期就删除。我们称这种方法为惰性策略。这种方式对CPU是友好的,但是也有一个相应的问题,就是如果我们永远不访问这些过期的key,它们永远不会被删除。在实际实现Redis服务器的时候,会用到上面两种方式,这样可以得到一个折中的方法。另外,在计时策略中,我们可以从官网看到如下说明具体是Redis每秒做10次:从关联过期的key集合中随机测试20个key。删除所有发现过期的密钥。如果超过25%的key过期,则从步骤1重新开始。也就是说Redis会从设置过期时间的key中随机选择20个key,删除已经过期的key,如果超过25则重新执行操作%。每秒执行10次这样的操作。5.小结今天介绍一下Redis的内存回收和Key过期策略处理。Redis是必不可少的开发组件,我们一定要掌握好它。希望今天的文章能帮助大家更好的掌握Redis的核心。此外,欢迎大家在我们的知识星球上与我们一起进步。