面试官问:Redis缓存淘汰策略有哪些?

2024年 6月 4日 90.9k 0

我们知道:Redis是基于内存的,面试官问:

  • 生产环境Redis内存如何分配?
  • Redis键过期了如何删除?
  • ......

面试官问:Redis缓存淘汰策略有哪些?-1图片

本小节不仅适用于工作,也是面试的高频问题。

文章导读

面试官问:Redis缓存淘汰策略有哪些?-2图片

Redis内存分析

一、Redis默认内存是多少?

在 64bit 系统下,默认不限制内存大小,不设置内存大小和maxmemory = 0表示不限制 Redis 内存使用

二、如何查看Redis最大内存是多少?

  • 命令行
  • 127.0.0.1:6379> config get maxmemory
    1) "maxmemory"
    2) "0"
  • 配置文件 redis.conf
  • # maxmemory 

    三、如何查看Redis内存使用情况?

    127.0.0.1:6379> info memory

    四、如何配置和修改?

  • 临时方案,通过命令修改
  • 127.0.0.1:6379> config set maxmemory 104857600
    OK
    127.0.0.1:6379> config get maxmemory
    1) "maxmemory"
    2) "104857600"
  • 永久方案,通过配置文件
  • 面试官问:Redis缓存淘汰策略有哪些?-3图片

    五、生产环境如何配置?

    建议:一般取物理内存的3/4

    Redis过期键删除?

    我们知道,redis一般会设置过期时间。那么这些键过期了是立刻从内存中删除吗?

    通常,键删除会有不同的策略

    一、立刻删除

    立即删除能保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是删除操作会占用cpu的时间,造成CPU额外的压力。

    redis.conf 中,通过调整过期键的检测频率

    # The range is between 1 and 500, however a value over 100 is usually not
    # a good idea. Most users should use the default of 10 and raise this up to
    # 100 only in environments where very low latency is required.
    hz 10

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

    二、惰性删除

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

    • 如果未过期,返回数据 ;
    • 发现已过期,删除,返回不存在。

    惰性删除策略的缺点是,它对内存是最不友好的。如果一个键已经过期,而这个键又仍然保留在redis中,那么只要这个过期键不被删除,它所占用的内存就不会释放。

    #开启憜性淘汰
    lazyfree-lazy-evictinotallow=yes

    三、定期删除

    这种方案有效规避上述两种极端情况, 定期删除策略的难点是确定删除操作执行的时长和频率:

    • 如果删除操作执行得太频繁或者执行的时间太长,定期删除策略就会退化成立即删除策略。
    • 如果删除操作执行得太少,或者执行的时间太短,定期删除策略又会和惰性删除束略一样,出现浪费内存的情况。
    • 因此,如果采用定期删除策略的话,服务器必须根据情况,合理地设置删除操作的执行时长和执行频率。

    Redis内存淘汰策略

    基于上述的了解,假如:

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

    2 惰性删除时,也从来没有被点中使用过

    上述两个步骤,依然会有大量过期的key堆积在内存中,导致redis内存空间紧张或者很快耗尽。

    因此,有没有一个更好的兜底方案......?这就是要讲的淘汰策略

    一、LRU和LFU区别?

    LRU(Least Recently Used,最近最少使用页面置换算法)

    假设我们有一个容量为3的LRU缓存,访问数据的顺序如下:

    • 访问数据1,缓存中现在有:[1]
    • 访问数据2,缓存中现在有:[1, 2]
    • 访问数据3,缓存中现在有:[1, 2, 3]
    • 再次访问数据1,缓存中现在有:[2, 3, 1](因为1被重新访问,它被移到了列表的末尾)
    • 访问数据4,由于缓存已满,最不常用的数据2将被淘汰,缓存中现在有:[3, 1, 4]

    原理:如果数据最近被访问过,那么在不久的将来它很可能再次被访问。因此,LRU会淘汰最长时间未被访问的数据。

    适用场景:适用于最近被访问的数据在未来某个时间点很可能再次被访问。

    LFU(Least Frequently Used,最近最不常用页面置换算法)

    假设我们有一个容量为3的LFU缓存,访问数据的顺序如下:

    • 访问数据1,计数器:{1: 1}
    • 访问数据2,计数器:{1: 1, 2: 1}
    • 访问数据1,计数器:{1: 2, 2: 1}
    • 访问数据3,计数器:{1: 2, 2: 1, 3: 1}
    • 访问数据1,计数器:{1: 3, 2: 1, 3: 1}
    • 访问数据4,由于缓存已满,访问次数最少的数据2将被淘汰,计数器:{1: 3, 3: 1, 4: 1}

    原理:LFU算法会跟踪每个页面在特定时间段内被访问的频率。当需要淘汰页面时,LFU算法会淘汰在该时间段内访问次数最少的页面。

    适用场景:LFU算法适用于那些访问模式可能随时间变化的场景,或者访问频率能够较好地反映页面重要性的情况。

    小结

    • LRU关注数据的最近访问时间,淘汰最长时间未被访问的数据。
    • LFU关注数据的访问频率,淘汰访问次数最少的数据。

    二、Redis有哪些淘汰策略?

    redis.config 配置文件中,

    # volatile-lru -> Evict using approximated LRU, only keys with an expire set.
    # allkeys-lru -> Evict any key using approximated LRU.
    # volatile-lfu -> Evict using approximated LFU, only keys with an expire set.
    # allkeys-lfu -> Evict any key using approximated LFU.
    # volatile-random -> Remove a random key having 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.

    解释下:

    volatile-lru:使用近似的最近最少使用(LRU)算法淘汰键。但是,只有那些设置了过期时间的键(即“volatile”键)才会被考虑淘汰。

    allkeys-lru:使用近似的LRU算法淘汰任何键,无论它们是否设置了过期时间。

    volatile-lfu:使用近似的最少频率使用(LFU)算法淘汰键。同样,只有设置了过期时间的键会被考虑。

    allkeys-lfu:使用近似的LFU算法淘汰任何键,不考虑它们是否设置了过期时间。

    volatile-random:随机淘汰一个设置了过期时间的键。

    allkeys-random:随机淘汰任何键,不论它们是否设置了过期时间。

    volatile-ttl:淘汰具有最短剩余生存时间(TTL)的键,即那些最接近过期时间的键。

    noeviction:不淘汰任何键。当内存达到最大容量时,Redis将不会进行任何淘汰操作,而是在写入新数据时返回错误。

    三、生产如何选择淘汰策略?

    在生产环境中选择缓存淘汰策略时,通常需要根据应用的具体需求和数据特性来定。这里给出常见案例:

    电商平台的商品推荐

    电商平台需要为用户展示个性化的商品推荐,其中热门商品的访问频率较高。可选择:LFU(Least Frequently Used)

    redis-cli config set maxmemory-policy allkeys-lfu

    因为LFU策略可以保留访问频率高的商品,确保推荐列表中展示用户最可能感兴趣的商品。

    金融交易平台的实时数据

    金融交易平台需要提供实时的股票价格和交易数据,数据的实时性至关重要。过期的时价被淘汰。

    可选择:TTL(Time To Live)结合LRU(Least Recently Used)

    redis-cli config set maxmemory-policy volatile-lru

    TTL确保数据在一定时间后自动过期,而LRU保证最近访问的数据被优先保留。

    电信运营商的用户数据管理

    电信运营商需要处理和缓存大量用户的通话记录、短信记录等,用户通常更关心最近的通信记录。

    可选择:LRU(Least Recently Used)

    redis-cli config set maxmemory-policy allkeys-lru

    因为LRU策略可以确保最近生成的通话记录和短信记录被优先缓存。

    社交媒体平台的用户动态

    社交媒体平台需要为用户展示好友的最新动态和帖子,用户通常对最新动态感兴趣。

    可选择:LRU

    redis-cli config set maxmemory-policy allkeys-lru

    因为LRU可以保证最新的帖子被优先展示。

    好了,今天就聊到这里,读者可依据实际情况择优选择策略。

    相关文章

    Oracle如何使用授予和撤销权限的语法和示例
    Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
    下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
    社区版oceanbase安装
    Oracle 导出CSV工具-sqluldr2
    ETL数据集成丨快速将MySQL数据迁移至Doris数据库

    发布评论