一文详解Redis缓存过期淘汰策略
一文带你详解Redis缓存过期淘汰策略,总体来说,可以从2个维度,四个方面来个8中淘汰策略分类过期键中筛选,volatile-ttl所有键中筛选,allkeys-lru、volatile-lru、allkeys-random、volatile-random、allkeys-lfu、volatile-lfulru(最近最久未使用的键删除)lfu(最低频次的键删除)random(随机删除)ttl(到了
1、Redis内存满了怎么办
1.1、如何查看Redis的默认内存,如何设置修改
1)查看+修改配置文件
- 打开redis配置文件
redis.conf
,输入:set nu
显示行号,设置maxmemory
参数,maxmemory是bytes字节类型,注意转换。
如下图,我设置最大内存为50m(即 5010241024byte)
maxmemory 52428800
2)使用命令查看及修改
## 获取最大内存
config get maxmemory
## 设置最大内存为100m,单位默认是byte,即 100*1024*1024(重启失效,如果永久修改,需要修改redis.conf)
config set maxmemory 104857600
或者info
命令来输出服务端、客户端、内存、CPU及其他的使用情况
info memory
只查看Redis内存的使用情况
1.2、redis占用物理机器多少内存,生产上如何配置
- 如果不设置最大内存大小或者设置最大内存大小为 0,在 64 位操作系统下不限制内存大小,在32位操作系统下最多使用 3GB 内存
- 在生产环境下,一般推荐Redis设置内存为最大物理内存的四分之三,也就是 0.75
1.3、redis 内存打满了或redis 内存使用超出了设置的最大值会怎样?
修改配置,故意把最大内存设置为 1byte,再通过 set k1 v1
命令,向 redis 中写入数据,redis 将会报错:(error) OOM command not allowed when used memory > ‘maxmemory’
- 如果设置了 maxmemory ,假如 redis 内存使用达到上限,并且 key 都没有加上过期时间,就会导致数据写爆 redis 内存。为了避免这样的情况,于是引出下一部分的内存淘汰策略
2、redis缓存淘汰策略
2.1、redis 如何删除设置了过期时间的 key
如果一个键是过期的,那它到了过期时间之后,不会马上就从内存中删除。
通过查看 redis 配置文件可知,默认淘汰策略是noeviction
(Don’t evict anything, just return an error on write operations,如果 redis 内存被写爆了,直接返回 error,或者通过命令查看:
config get maxmemory-policy
2.2、过期 key 的三种不同删除策略
1)定时删除
- 立即删除能保证内存中存储的数据是最新的,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对 CPU 是最不友好的,因为删除操作会占用 CPU 的时间,如果刚好碰上了 CPU 很忙的时候,比如正在许多复杂计算时,就会给 CPU 造成额外的压力,这会产生大量的性能消耗,同时也会影响数据的读取操作。
- 总结:定时删除对 CPU 不友好,但对 memory 友好,用处理器性能换取存储空间(拿时间换空间)
2)惰性删除
- 惰性删除的策略刚好和定时删除相反,惰性删除在数据到达过期时间后不做处理,等下次访问该数据时发现已过期,并将其删除,并返回不存在。过期键保留在Redis中,不被删除,它所占用的内存就不会释放。因此,惰性删除策略对内存是最不友好的。
- 在使用惰性删除策略时,如果数据库中有非常多的过期键,而这些过期键又恰好没有被访问到的话,那么它们也许永远也不会被删除(除非用户手动执行 FLUSHDB),我们甚至可以将这种情况看作是一种内存泄漏,即无用的垃圾数据占用了大量的内存,而服务器却不会自己去释放它们
- 总结:惰性删除对 memory 不友好,但对 CPU 友好,用存储空间换取处理器性能(拿空间换时间)
3)定期删除
- 定期删除策略是前两种策略的折中:定期删除策略每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影响。其做法为:周期性轮询 redis 库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度。
定期删除的特点
- CPU 性能占用设置有峰值,检测频度可自定义设置
- 内存压力不是很大,长期占用内存的冷数据会被持续清理
- 周期性抽查存储空间(随机抽查,重点抽查)
惰性删除和定期删除都存在数据没有被抽到的情况,如果这些数据已经到了过期时间,没有任何作用,这会导致大量过期的 key 堆积在内存中,导致 redis 内存空间紧张或者很快耗尽
因此必须要有一个更好的兜底方案,接下来引出 redis 内存淘汰策略
2.3、redis6中的内存淘汰策略有哪些?
见Redis的配置文件redis.conf:
解释如下:
- noeviction:不会驱逐任何key(默认的淘汰策略)
- allkeys-lru:对所有key使用LRU算法进行删除(推荐使用)
- volatile-lru:对所有设置了过期时间的key使用LRU算法进行删除
- allkeys-random:对所有key随机删除
- volatile-random:对所有设置了过期时间的key随机删除
- volatile-ttl:删除马上要过期的key
- allkeys-lfu:对所有key使用LFU算法进行删除
- volatile-lfu:对所有设置了过期时间的key使用LFU算法进行删除
总结和归纳
总体来说,可以从2个维度,四个方面来个8中淘汰策略分类:
从2个维度中筛选key:
- 过期键中筛选,volatile-ttl
- 所有键中筛选,allkeys-lru、volatile-lru、allkeys-random、 volatile-random、allkeys-lfu、volatile-lfu
从4个方面上筛选key:
- lru(最近最久未使用的键删除):allkeys-lru、volatile-lru
- lfu(最低频次的键删除):allkeys-lfu、volatile-lfu
- random(随机删除):allkeys-random、 volatile-random
- ttl(到了过期时间的键删除):volatile-ttl
2.4、生产环境中,如何配置缓存淘汰策略
- 生产环境中,推荐使用allkeys-lrul作为内存的淘汰策略,保证对所有key使用LRU算法进行删除
- 通过修改文件配置(永久生效):配置 maxmemory-policy 字段
maxmemory-policy allkeys-lru
- 使用命令查询和设置淘汰策略:
## 设置内存数据的淘汰策略为volatile-lru
config set maxmemory-policy volatile-lru
config get maxmemory-policy
更多推荐
所有评论(0)