背景:
Redis 是个基于内存的缓存数据库,既然是基于内存的,那肯定就会有存满的时候,再有新的数据就存不进去了。
此时 Redis 会执行已经定义好的一些淘汰策略,本文大概讲一下 Redis 的 8 种数据淘汰策略。
1.简介
8种内存淘汰策略:
当 Redis 达到最大内存限制时,Redis会确切地使用配置好的最大内存策略指令来执行。相关策略如下:
1.noeviction
(默认策略): 不会删除任何数据,拒绝所有写入操作并返回客户端错误消息(error)OOM command not allowed when used memory,此时 Redis 只响应删和读操作;
2.allkeys-lru
: 从所有 key 中使用 LRU 算法进行淘汰(LRU 算法:最近最少使用算法);
3.allkeys-lfu
: 从所有 key 中使用 LFU 算法进行淘汰(LFU 算法:最不常用算法,根据使用频率计算,4.0 版本新增);
4.volatile-lru
: 从设置了过期时间的 key 中使用 LRU 算法进行淘汰;
5.volatile-lfu
: 从设置了过期时间的 key 中使用 LFU 算法进行淘汰;
6.allkeys-random
: 从所有 key 中随机淘汰数据;
7.volatile-random
: 从设置了过期时间的 key 中随机淘汰数据;
8.volatile-ttl
: 在设置了过期时间的key中,淘汰过期时间剩余最短的。
注意: 当使用 volatile-lru、volatile-lfu、volatile-random、volatile-ttl 这四种淘汰策略时,如果没有 key 可以淘汰,则和 neoviction 一样返回错误。
2.如何选择使用哪种淘汰策略
根据应用程序的访问模式,选择正确的淘汰策略很重要,但是你可以在程序运行时重新配置策略,并使用 Redis 的 info 命令 输出来监控缓存未命中和命中的数量,以调整设置。
- keyspace_hits:缓存命中的次数
- keyspace_misses:没有命中的次数
- 缓存命中率 = keyspace_hits / (keyspace_hits + keyspace_misses)
一般根据经验来说:
-
使用 allkeys-lru 策略场景:
1.当你期望元素的子集将比其他元素更频繁地被访问时,比如幂律分布,20%的数据占有80%的使用次数;
2.当你不确定使用哪种策略时。
-
使用 allkeys-random 策略场景:
1.当你有一个循环访问,其中所有 key 进行会被连续地访问;
2.当你希望所有 key 的分布比较均匀。
-
使用 volatile-ttl 策略场景:
1.当你大部分缓存都设有不同的 ttl 值,向 Redis 提供过期候选的提示时。
注意: 给 key 设置过期时间会占用内存,因此使用 allkeys-lru
这样的策略更节省内存,因为在内存压力下不需要过期配置就可以收回密钥。
3.查询、设置内存淘汰策略
1)查询当前内存淘汰策略
127.0.0.1:6379> config get maxmemory-policy
2)获取Redis能使用的最大内存大小
127.0.0.1> config get maxmemory
说明:
-
如果不设置最大内存大小或设置最大内存大小为 0,
-
在 64 为操作系统下不设置内存大小,
-
在 32 为操作系统下最多使用 3GB 内存。
32 位的机器最大只支持 4GB 的内存,而系统本身就需要一定的内存资源来支持运行,所以 32 位机器默认限制最大 3GB 的可用内存。
3)设置淘汰策略
方法一:通过配置文件设置淘汰策略(修改 redis.conf 文件):
maxmemory-policy allkeys-lru
方法二:通过命令修改淘汰策略(临时生效,重启恢复):
127.0.0.1:6379> config set maxmemory-policy allkeys-lru
4)设置 Redis 最大占用内存大小
设置 Redis 最大占用内存大小为 100M(临时生效,重启恢复):
127.0.0.1:6379> config set maxmemory 100mb
整理完毕,完结撒花~
参考地址:
1.官方文档,https://redis.io/docs/reference/eviction/
2.Redis学习(二)原理篇,https://blog.csdn.net/qq_33204709/article/details/122326901
3.Redis 6种淘汰机制,看看你知道哪些?,https://blog.csdn.net/qq_42914528/article/details/126151403