目录
1. Redis 的过期淘汰策略
1.1 说一下定期删除的执行流程
2. Redis 的内存淘汰策略
2.1 LRU 和 LFU 有什么区别
3. Redis 中的过期淘汰策略和内存淘汰策略有什么区别
1. Redis 的过期淘汰策略
在了解过期淘汰策略之前,我们首先要知道 Redis 中的键值过期之后,是不会立即删除的,因为 Redis 本身是单线程执行的,如果某个键值过期之后,立马就删除它,那么删除操作可能就会影响主业务的执行,所以当某个键值过期之后,在物理层面来说不会立即删除,而是等待某个时机一起删除。
Redis 有两种过期淘汰策略:
1. 惰性删除:不主动删除过期键,而是等到每次从数据库访问键值的时候,顺便判断一下当前键值是否过期,如果过期则删除过期键值,并返回 null。
① 优点:每次访问键值的时候,才会判断是否过期,使用较少的系统资源。
② 缺点:如果过期键值比较多的时候,就会导致系统占用空间删除不及时,空间利用率低,造成一定的空间浪费。
2. 定期删除:每隔一段时间检查一次数据库,随机删除一些过期键。
① 优点:通过限制删除操作的时长和频率,减少删除操作对 Redis 主业务的影响,同时在过期键值比较多的时候,删除一部分过期数据,提高空间利用率。
② 缺点:当过期键值比较多的时候,定期删除过期键可能会占用比较多的 CPU 时间,可能会对服务器的响应时间和吞吐量造成影响。
1.1 说一下定期删除的执行流程
定期删除的执行流程如下:
- 从过期字典中随机取出 20 个键;
- 删除这 20 个键中过期的键;
- 如果过期 key 的比例超过 25%,则重复步骤 1,2.
上图中判断过期键是否超过 25% 是这样计算的:
每次取 20 个元素,如果过期 10 个,那么占比就是 10 / 20 = 50%,超过 25%,继续取 20 个元素,以此类推... 同时为了避免过期扫描不会出现循环过度,导致线程卡死现象,还设置了扫描时间的上限,默认不会超过 25ms。
2. Redis 的内存淘汰策略
Redis 的内存淘汰一共有 8 种,
Redis 4.0 之前,有 4 大类(6 种)淘汰策略:
🍁第一类:Redis 默认的淘汰策略
① noeviction 不淘汰任何数据,当内存不足的时候,再进行新增操作就报错;
🍁第二类:随机淘汰键值
② allkeys-random:随机淘汰任意键值
③ volatile-random:随机淘汰设置了过期时间的任意键值
🍁第三类:淘汰最久未使用的键值
④ allkeys-lru:淘汰整个键值中最久未使用的键值;
⑤ volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值;
🍁第四类:淘汰更早过期的键值
⑥ volatile-ttl:优先淘汰更早过期的键值。
Redis 4.0 之后,有新增了 2 种淘汰机制:
① volatile-lfu:淘汰所有设置了过期时间的键值中,使用最少的键值;
② allkeys-lfu:淘汰所有键值中最少使用的键值。
allkeys-xxx 表示从所有的键值中淘汰数据,volatile-xxx 表示从设置了过期时间的键值中淘汰数据。
2.1 LRU 和 LFU 有什么区别
LRU (Least Recently Used,最少使用)和 LFU (Least Frequently Used,最不常使用)都是 Redis 中的内存淘汰策略,他们的区别如下:
① LRU(最少使用):LRU 策略基于时间概念,它认为最近被访问的键很有可能被再次访问,因此它会淘汰最久未被访问的键。它内部维护了一个顺序列表,当某个键被访问了,它就会被移到列表末尾,最久未被访问的键在列表的前面,所以淘汰的时候,从列表前面开始淘汰。
② LFU(最不常使用):LFU 策略基于频率概念,它认为访问次数最少的键是最不常使用的,因此它会淘汰访问次数最少的键。它内部维护了一个计数器,键值每次被访问的时候,计数器就会增加。
LFU 可以认为是对 LRU 的一个补充,因为 LRU 中可能会出现这种情况:一个键很久都没被访问了,突然被访问了一次,之后很久都不会被访问了,但是 LRU 也不会淘汰它,这样其实是不合理的。
3. Redis 中的过期淘汰策略和内存淘汰策略有什么区别
① 过期淘汰策略:过期淘汰策略是 Redis 的一种优化手段,主要是为了删除过期数据的。
② 内存淘汰策略:内存淘汰策略是为了解决一个问题,它是为了解决 Redis 运行内存过大的问题,总共有 8 中内存淘汰策略。