以下所有演示均在 Redis7.0.12 版本进行,版本不同,配置文件行号可能略有差异请注意
1. 最大缓存设置
1.1 配置文件设置
1119 行:maxmemory <bytes>
配置,单位 byte 默认没有配置。当没设置 maxmemory
或 值为 0 时,表示没有大小限制。
优点: 重启配置不丢失
缺点: 修改配置文件需要重启 Redis 服务
1.2 命令设置
docker start redis
docker exec -it redis redis-cli -a 111111
# 查看
config get maxmemory
# 修改:最大内存 10 Byte
config set maxmemory 10
优点: 修改立即生效
缺点: 服务重启配置丢失,需要重新设置
2. Redis 数据如何删除
2.1 立即删除
Redis不可能时刻遍历所有被设置了生存时间的key,来检测数据是否已经达到过期时间,然后对它进行删除。
立即删除能保证内存中数据最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对cpu是最不友好的,因为删除操作会占用cpu的时间,如果正好碰到cpu很忙的时候,就会给cpu造成额外的压力
总结: 对CPU不友好,用处理器性能换取存储空间(拿时间换空间)
2.2 惰性删除
数据到达过期时间,不做处理,等下次访问时,如果未过期,返回数据。如果过期了,删除并返回 nil。
惰性删除的缺点时:对内存不友好,如果一个键已经过期,而这个键此后没有被访问将一直留在内存中,所占用内存空间不会释放。
如果 Redis 中有非常多的过期键,而这些过期键又恰好都没有被访问到的话,那么他们也许永远不会被删除(除非用户手动执行FLUSHDB),我们甚至可以讲这中情况看做内存泄露。这对于运行状态非常依赖内存的Redis服务器来说,肯定不是一个好消息。
2.3 定期删除
定期删除策略每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行时长和频率来减少删除操作对CPU时间的影响。
可以通过配置文件的 hz
属性控制,默认为 10,表示 1s 进行 10 次扫描(100ms 一次)。hz 范围 1~ 500,Redis 作者也不建议将这个属性调整太高。
定期删除也是间隔一定时间抽查部分数据,仍然这仍然会存在数据删除不及时的问题。因此我们必须有一个兜底策略:缓存淘汰策略,当 Redis 内存不足时,进行兜底。
3. 缓存淘汰策略
配置文件:1148行
maxmemory-policy noeviction
默认配置:noeviction
命令行:config set maxmemory-policy xxx
volatile-lru
:使用近似的LRU(最近最少使用)算法删除数据,但仅针对设置了过期时间的键。allkeys-lru
:使用近似的LRU算法来逐出任何键,无论是否设置了过期时间(所有键)。volatile-lfu
:使用近似的LFU(最不经常使用)算法来逐出数据,但仅针对设置了过期时间的键。allkeys-lfu
:使用近似的LFU算法来逐出任何键,无论是否设置了过期时间。volatile-random
:随机逐出一个设置了过期时间的键。allkeys-random
:随机逐出任何一个键,无论是否设置了过期时间。volatile-ttl
:逐出具有最近过期时间(即TTL最小)的键。noeviction
:不逐出任何键,在写操作时仅返回错误,默认 Redis 缓存淘汰策略是这个。
若无特殊要求,通常配置的是:allkeys-lru,基于 LRU(最近最少使用)算法删除键。
2.1 LRU
LRU算法是一种基于时间局部性原理的缓存替换算法。它的基本思想是,如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。因此,当缓存空间不足时,会优先淘汰最长时间未被访问的数据(优先删除访问时间最久的数据)。
2.2 LFU
LFU算法是一种基于频率局部性原理的缓存替换算法。它的基本思想是,如果一个数据在一定时间段内被访问的次数越少,那么它在未来被访问的可能性也越低。因此,当缓存空间不足时,会优先淘汰访问频率最低的数据(优先删除访问频率最低的)。
2.3 缓存淘汰策略演示
config get maxmemory-policy
# 1) "maxmemory-policy"
# 2) "noeviction"
# 1. 修改最大内存 2M 2097152
config set maxmemory 2097152
FLUSHALL
docket exec -it redis /bin/bash
cd /tmp/
# 创建 2w 的数据
for((i=1;i<=2*10000;i++)); do echo "set k$i v$i" >> /tmp/redisTest.txt ;done;
# 1. noeviction:OOM 失败 6737 条
# cat /tmp/redisTest.txt | redis-cli -a 111111 --pipe 使用管道批量导入命令
cat /tmp/redisTest.txt | redis-cli -a 111111 --pipe
# 重置环境
config set maxmemory-policy allkeys-lru
config set maxmemory 2097152
FLUSHALL
# 2. allkeys-lru
cat /tmp/redisTest.txt | redis-cli -a 111111 --pipe
缓存淘汰策略:allkeys-lru 时导入全部成功,不过 get k1
获取不到对应的值
缓存淘汰策略:noeviction 时导入OOM失败 6737 条记录