Redis 缓存淘汰策略

lz 1年前 ⋅ 859 阅读

常见的问题

1、生产上你们的 redis 设置的内存多少?

2、如果配置、修改 redis 内存的大小?

3、如果内存满了你怎么办?

4、redis 清理内存的方式?定期删除和惰性删除了解过吗?

5、redis 缓存淘汰策略

6、redis 的 lru 了解过吗?是否可以手写一个 lru 算法?

redis 内存满了怎么办?

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

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

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

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

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

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

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

通过修改文件配置:

或者通过命令修改:

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

info memory

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

1、如果要是 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 时间过多的消耗在删除过期键上,如果删除操作执行得太少,或者给你的时间太短,定期删除策略又会和惰性删除策略一样,出现浪费内存的情况。因此,如果采用定期删除策略的话,服务器必须根据情况,合理的配置删除操作执行时间长短和执行频率。

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

依旧有漏网之鱼

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

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

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

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

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

内存淘汰策略

redis.conf

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、命令方式

2、配置文件方式

 

--end--

 

版权 本文为TIMO社区原创文章,转载无需和我联系,但请注明来自TIMO社区 http://timo.aikanmv.cn