02_Redis 缓存淘汰策略

以下所有演示均在 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 作者也不建议将这个属性调整太高。
hz 配置

定期删除也是间隔一定时间抽查部分数据,仍然这仍然会存在数据删除不及时的问题。因此我们必须有一个兜底策略:缓存淘汰策略,当 Redis 内存不足时,进行兜底。

3. 缓存淘汰策略

配置文件:1148行 maxmemory-policy noeviction 默认配置:noeviction
命令行:config set maxmemory-policy xxx
Redis 缓存淘汰策略

  • 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 获取不到对应的值
allkeys-lru
缓存淘汰策略:noeviction 时导入OOM失败 6737 条记录
noeviction

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值