Redis内存优化

过期键删除策略

为什么要有删除策略?

首先,Redis 的数据过期了就会马上删除么?

不是。

常见的三种策略

定时删除

在设置某个key 的过期时间同时,我们创建一个定时器,让定时器在该过期时间到来时,立即执行对其进行删除的操作。

优点:定时删除对内存是最友好的,能够保存内存的key一旦过期就能立即从内存中删除。

缺点:

  • CPU占用率高

  • 当 key 已过期,但是定时器还处于未唤起状态,这段时间内 key 仍然可以用。

定期删除策略

Redis定期地随机选择一些键进行检查,如果发现这些键已经过期,则删除这些键。

优点:CPU占用率比定时删除低。也能有效释放过期键占用的内存。

缺点:

  • 难以确定删除操作执行的时长和频率。

    • 如果执行的太频繁,定期删除策略变得和定时删除策略一样,对CPU不友好。

    • 如果执行的太少,那又和惰性删除一样了,过期键占用的内存不会及时得到释放。

  • 在获取某个键时,如果某个键的过期时间已经到了,但是还没执行定期删除,那么就会返回这个键的值,这是业务不能忍受的错误。

惰性删除策略

惰性删除不会去主动删除数据。而是在访问数据的时候,先判断 key 是否过期,如果过期则删除并返回 null 给客户端

优点:CPU占用率低

缺点:可能导致空间浪费。删除过期键不及时,造成了一定的空间浪费。

实际开发

一般是定期删除 + 惰性删除策略配合使用

定期删除策略降低了对 CPU 资源的损耗,惰性删除策略互补了未检查到的key,基本上满足了所有要求。

内存淘汰机制

概述

作用

当 Redis 的运行内存已经超过 Redis 设置的最大内存之后,则会使用内存淘汰策略删除符合条件的 key,以此来保障 Redis 高效的运行。

内存淘汰策略

1、不进行数据淘汰的策略

  • noeviction:当运行内存超过最大设置内存时,不淘汰任何数据,这时如果有新的数据写入,则会触发 OOM 默认

2、进行数据淘汰的策略

在设置了过期时间的数据中进行淘汰:

  • volatile-random:随机淘汰设置了过期时间的任意键值

  • volatile-ttl:优先淘汰更早过期的键值

  • volatile-lru:淘汰所有设置了过期时间的键值中,最近最少使用的键值

  • volatile-lfu:淘汰所有设置了过期时间的键值中,使用频率最少的键值

在所有数据范围内进行淘汰:

  • allkeys-random:随机淘汰任意键值

  • allkeys-lru:淘汰整个键值中,最近最少使用的键值 最常用

  • allkeys-lfu:淘汰整个键值中,使用频率最少的键值

前缀为volatile-和allkeys-的区别:二者选择要清除的键时的字典不同

  • volatile-策略:从redisDb中的expire字典中选择键进行清除

  • allkeys-策略:从dict字典中选择键进行清除

配置

查看当前Redis使用的内存淘汰策略

使用 config get maxmemory-policy 命令

 127.0.0.1:6379> config get maxmemory-policy
 1) "maxmemory-policy"
 2) "noeviction"

可以看出,当前 Redis 使用的是 noeviction 类型的内存淘汰策略,它是 Redis 3.0 之后默认使用的内存淘汰策略,表示当运行内存超过最大设置内存时,不淘汰任何数据,但新增操作会报错。

如何修改 Redis 内存淘汰策略?

设置内存淘汰策略有两种方法:

  • 方式一:通过“config set maxmemory-policy <策略>”命令设置。它的优点是设置之后立即生效,不需要重启 Redis 服务,缺点是重启 Redis 之后,设置就会失效。

  • 方式二:通过修改 Redis 配置文件修改,设置“maxmemory-policy <策略>”,它的优点是重启 Redis 服务后配置不会丢失,缺点是必须重启 Redis 服务,设置才能生效。

如何避免内存爆炸?

1、给缓存内容设置超时时间

但是这样删除不了无超时时间的key

2、定期删除

3、惰性删除

通过请求发现过期key,然后删除

4、内存淘汰策略

image-20220830下午95658701