赞
踩
参考:来自小林大佬的文章
redis出于性能上的考虑,无法做到对每一个过期的key进行即时的过期监听和删除。但是redis提供了其它三种方法来清理过期key:
1、惰性删除(被动清理)
2、定时删除(主动清理)
3、定期删除(内存不足时触发主动清理)
Redis 的定期删除的流程:
- 从过期字典中随机抽取
20
个 key;- 检查这 20 个 key 是否过期,并删除已过期的 key;
- 如果本轮检查的已过期 key 的数量,超过 5 个(20/4),也就是「已过期 key 的数量」占比「随机抽取 key 的数量」大于
25%
,则继续重复步骤 1;如果已过期的 key 比例小于 25%,则停止继续删除过期 key,然后等待下一轮再检查。
可以看到,定期删除是一个循环的流程。
那 Redis 为了保证定期删除不会出现循环过度,导致线程卡死现象,为此增加了定期删除循环流程的时间上限,默认不会超过25ms
。
补充面试相关问题:
Redis瞬间有大量key失效,为什么会影响别的key的读取性能?(这里需从底层原理进行分析)
因为 Redis 定期删除的定时任务,是在Redis主线程中执行的。也就是说如果在执行定期删除的过程中,出现了需要大量删除过期key的情况,那么在业务访问时,必须等这个过期任务执行结束,才可以处理业务请求。此时就会出现,业务访问延时增大的问题,最大延迟为25毫秒。
前面的三种过期删除策略,每一种都有优缺点,仅使用某一个策略都不能满足实际需求。
所以, Redis 选择「惰性删除+定期删除」这两种策略配和使用,以求在 合理使用CPU资源 和 避免内存浪费 之间取得平衡。
在配置文件 redis.conf 中,可通过参数 maxmemory <bytes>
来设定最大运行内存。只有在Redis的运行内存达到了我们设置的最大运行内存,才会触发内存淘汰策略。
最近最少使用,会选择淘汰最近最少使用的数据。
传统的LRU算法:基于哈希链表的结构,按照最后操作key(包含读key或写key操作)的时间顺序来排列。链表头进尾出,最新被操作的键会被移除并重新插入到链表头部。所以触发内存淘汰策略时,哈希链表的尾部就是 最久未被操作过 的元素,直接删除淘汰即可。
Redis的LRU类似于此方式,但为了节省内存做了改进,不完全相同…(具体参考 来自小林大佬的文章)
2、LFU(Least Frequently Used):
最近最不常用的,LFU 算法是根据数据访问频率(并非单纯的访问次数)来淘汰数据的,它的核心思想是 “如果数据过去被访问多次,那么将来被访问的频率也更高”。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。