美文网首页JavaJava 程序员
Redis 缓存淘汰策略

Redis 缓存淘汰策略

作者: 程序花生 | 来源:发表于2022-04-19 17:04 被阅读0次

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

    常见的问题

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

    总结: 定期抽样 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、配置文件

    作者:心城以北
    链接:https://juejin.cn/post/7063998360469897229
    来源:稀土掘金

    相关文章

      网友评论

        本文标题:Redis 缓存淘汰策略

        本文链接:https://www.haomeiwen.com/subject/vsasertx.html