Redis内存优化
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、内存淘汰策略