likes
comments
collection
share

Redis 缓存淘汰策略

作者站长头像
站长
· 阅读数 16

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」。

本文主要讲解了 redis 缓存过期淘汰策略, 后面我们会结合 LeetCode 的 LRU 算法题目,自己动手实现 LRU 的算法案例(LRU 算法实践)。

常见的问题

1、生产上你们的 redis 设置的内存多少? 2、如果配置、修改 redis 内存的大小? 3、如果内存满了你怎么办? 4、redis 清理内存的方式?定期删除和惰性删除了解过吗? 5、redis 缓存淘汰策略 6、redis 的 lru 了解过吗?是否可以手写一个 lru 算法?

redis 内存满了怎么办?

redis 默认内存多少? 在哪里查看?如何设置和修改?

1、查看 redis 最大占用内存?

Redis 缓存淘汰策略

2、redis 默认内存多少可以用?

如果不设置最大内存大小或者设置对打内存大小 0 , 在 64 位操作系统下不限制内存大小,在 32位操作系统下最多使用 3G 内存

3、一般生产上你如何配置?

一般推荐 reids 设置内存为最大物理内存的 3/4

4、如何修改 redis 内存设置?

通过修改文件配置

Redis 缓存淘汰策略

通过命令修改

Redis 缓存淘汰策略

5、什么命令查看 redis 内存使用情况?

info memory

Redis 缓存淘汰策略

如果要是 redis 的内存满会怎么样?如果redis 内存使用超过了最大设置会怎么样?

1、如果要是 redis 的内存满会怎么样?如果redis 内存使用超过了最大设置会怎么样?

Redis 缓存淘汰策略

如果 redis 内存被打满了,会提示 “(error) OOM command not allowed when used memory > 'maxmemory'.”

结论

  • 设置了 maxmemory 的选项,加入 redis 内存使用达到了上限
  • 没有加上过期时间就会导致数据写满 maxmemory 为了避免这个问题,下面我们将在内存淘汰策略中详细阐述

redis 缓存淘汰策略?

1、往 redis 里面写了数据但是为什么会没了?

redis 过期键的删除策略

  • 如果一个键是过期的,那它到了过期时间之后是不是马上就从内存中被删除了呢?
  • 肯定不是
  • 如果不是,那过期之后到底什么时候被删除?? 是一个什么操作

三种不同的删除策略

1、定时删除

Redis 不可能时时刻刻遍历所有被设置了生存时间的key, 来检查数据是否已经到达过期时间,然后对他进行删除。

立即删除能把整内存中数据最大的新鲜度,因为它保证过期键值会在过期后马上被删除,其所占的内存也会随之释放,但是立即删除对 CPU 是最不友好的。因为删除操作会占用 CPU 的时间,如果刚好碰到 CPU 很忙的时候,比如正在做交集或者排序等计算的时候,这个时候会给 CPU 造成额外的压力,让 CPU 心累,有时候需要删除。忙死。。。。

这个时候会产生大量的性能消耗,同时也会影响数据的读取操作。

总结:对 CPU 不友好,用处理器吸能换存储空间(拿时间换空间)。


2、惰性删除

数据到达过期时间,不做处理,等下次访问该数据时,

如果未过期,返回数据:

发现已过期,删除,返回不存在

惰性删除策略的缺点是,它对内存最不友好的。

如果一个键已经过期,而这个键仍保留在数据库中, 那么只要这个过期键不被删除,它所占用的内存就不会释放。

在使用惰性删除策略时,如果数据库有非常多的过期键,而这这些过期键恰好🈶️没有被访问的话,那么他们也许永远不会被删除(除非用户手动执行 flushdb), 我们甚至可以将这种情况看作是一种内存泄漏 - 无用的垃圾数据占用了大量的内存,而服务器却不会自己去释放他们,这对于运行状态非常依赖与内存的 Redis 服务器来说,肯定不是一个好消息。

总结:对 memory 不友好,用存储空间换处理器性能(拿空间换时间)


3、上面两种方案都走极端

定期删除

定期删除策略是前面两种策略的择中

定期删除策略每间隔一段时间执行一次删除过期键操作,并且通过限制删除操作执行的时间和频率来减少删除操作对 CPU 时间的影响。

周期性轮询 redis 库中时效性数据,采用随机抽泣的策略,利用过期数据占比的方式控制删除频度

特点1:CPU 性能占用设置有峰值, 检测频度可自己自定义设置。

特点2: 内存压力不是很大,长期占用内存的冷数据会被持续清理

总结:周期性抽查存储空间(随机抽查,重点抽查)

举个例子:

redis 默认每100ms 检查,是否有过期的 key, 如果有 key 则删除。注意: redis 不是间隔 100ms 将所有的 key 检查一次而是随机抽取进行检查(如果每间隔 100ms , 全部 key 进行检查,redis 直接进入 icu ). 如果只采用定期删除策略,会导致很多 key 到时间没有删除。

定期删除策略的难点是确定删除操作执行的时长和频率。如果删除操作执行得太频繁,或者执行操的时间太长,定期删除策略就会退化成定时删除策略,以至于 CPU 时间过多的消耗在删除过期键上,如果删除操作执行得太少,或者珍惜i给你的时间太短,定期删除策略又会和惰性删除策略一样,出现浪费内存的情况。因为,如果采用定期删除策略的话,服务器必须根据情况,合理的删除操作执行时间长短和执行频率。

总结: 定期抽样 key , 判断是否过期

依旧有漏网之鱼

上述步骤都通过了,还有漏洞吗?

1、定期删除,从来没有被抽查到

2、惰性删除,也从来没有被点中过

上述2步骤 ==> 大量过期 key 堆积唉内存中,导致 redis 内存空间紧张或者很快耗尽。

必须要要有一个更好的兜底方案 。。。。。

内存淘汰策略

redis.conf

Redis 缓存淘汰策略

redis 的 8 种淘汰策略

官方配置文件中的原文:

volatile-lru -> Evict using approximated LRU among the keys with an expire set.
allkeys-lru -> Evict any key using approximated LRU.
volatile-lfu -> Evict using approximated LFU among the keys with an expire set.
allkeys-lfu -> Evict any key using approximated LFU.
volatile-random -> Remove a random key among the ones with an expire set.
allkeys-random -> Remove a random key, any key.
volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
noeviction -> Don't evict anything, just return an error on write operations.

默认配置: noeviction

中文总结

1、noevication : 不会驱逐任何 key (默认)

2、allkeys-lru: 对所有的 key 使用 lru 算法进行删除

3、volatile-lru: 对所有的设置了过期时间的 key 进行 lru 算法进行删除

4、allkeys-random: 对所有 key 随机删除

5、volatile-random: 对所有设置了过期时间的 key 随机删除

6、volatile-ttl :马上删除要过期的 key

7、allkeys-lfu: 对所有 key 进行 lfu 算法进行删除

8、volatile-lfu: 对所有设置了过期时间的 key 使用 lfu 算法进行删除

总结:

  • 2 * 4 = 8
  • 两个维度: 过期键中筛选;所有键中筛选
  • 4个方面: LRU ,LFU , random , ttl
  • 8 个选项

你平时用那种?

一般平时用 : allkeys-lru

如何修改

1、命令方式

Redis 缓存淘汰策略

2、配置文件

Redis 缓存淘汰策略

转载自:https://juejin.cn/post/7063998360469897229
评论
请登录