vlambda博客
学习文章列表

[精选]Redis的内存过期与淘汰策略是如何工作的?


文章来自:https://leetcode-cn.com/circle/article/ztZkJJ/









精选文章正文

1 Redis从入门到精通视频教程+笔记+资料【PHP版】
链接:
http://www.mano100.cn/thread-1607-1-1.html

2 大厂面试必备Redis入门到高并发秒杀实战教程
链接:
http://www.mano100.cn/thread-1700-1-1.html

3 2020redis面试全套视频教程
链接:
http://www.mano100.cn/thread-1588-1-1.html

Redis 内存回收机制

Redis 的内存回收主要围绕以下两个方面:

1.Redis 过期策略:删除过期时间的 key 值

2.Redis 淘汰策略:内存使用到达 maxmemory 上限时触发内存淘汰数据


Redis 的过期策略和内存淘汰策略不是一件事,实际研发中不要弄混淆了,下面会完整的介绍两者。


Redis过期策略

过期策略通常有以下三种:

1.定时过期

每个设置过期时间的 key 都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的 CPU 资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。


2.惰性过期

所谓惰性策略就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。

定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,即当你主动去查过期的key时,如果发现key过期了,就立即进行删除,不返回任何东西.

总结:定期删除是集中处理,惰性删除是零散处理。

3.定期过期

redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。

Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。

1.从过期字典中随机 20 个 key;

2.删除这 20 个 key 中已经过期的 key;

3.如果过期的 key 比率超过 1/4,那就重复步骤 1;

redis默认是每隔 100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载。

Redis中同时使用了惰性过期和定期过期两种过期策略。

Redis 淘汰策略

先聊一下为什么需要淘汰策略。有了以上过期策略的说明后,就很容易理解为什么需要淘汰策略了,因为不管是定期采样删除还是惰性删除都不是一种完全精准的删除,就还是会存在key没有被删除掉的场景,所以就需要内存淘汰策略进行补充。


1.简介

Redis 的内存淘汰策略,是指当内存使用达到 maxmemory 极限时,需要使用 LAU 淘汰算法来决定清理掉哪些数据,以保证新数据的存入。


2、LRU 算法

Redis 默认情况下就是使用 LRU 策略算法。


实现方式

[精选]Redis的内存过期与淘汰策略是如何工作的?

1. 新增key value的时候首先在链表结尾添加Node节点,如果超过LRU设置的阈值就淘汰队头的节点并删除掉HashMap中对应的节点。

2. 修改key对应的值的时候先修改对应的Node中的值,然后把Node节点移动队尾。

3. 访问key对应的值的时候把访问的Node节点移动到队尾即可。


3.缓存清理配置

maxmemory 用来设置 redis 存放数据的最大的内存大小,一旦超出这个内存大小之后,就会立即使用 LRU 算法清理掉部分数据。


对于 64 bit 的机器,如果 maxmemory 设置为 0,那么就默认不限制内存的使用,直到耗尽机器中所有的内存为止,但是对于 32 bit 的机器,有一个隐式的闲置就是 3GB。


4.Redis 数据淘汰策略

maxmemory-policy,可以设置内存达到最大闲置后,采取什么策略来处理。


对应的淘汰策略规则如下:


1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。


2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key。


3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key。


4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key。


5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。


6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。


5.缓存清理的流程

1)客户端执行数据写入操作


2)redis server 接收到写入操作之后,检查 maxmemory 的限制,如果超过了限制,那么就根据对应的 policy 清理掉部分数据


3)写入操作完成执行。


总结

redis 的内存淘汰策略用于处理内存不足时的需要申请额外空间的数据,内存淘汰策略的选取并不会影响过期的 key 的处理。过期策略用于处理过期的缓存数据。




以上是本文的全部内容,希望对大家的学习有帮助,也希望大家多多支持php自学中心