Redis 的内存淘汰策略详解

发布于:2025-08-20 ⋅ 阅读:(19) ⋅ 点赞:(0)

在高并发场景中,Redis 常被用作缓存以减轻数据库压力。但由于 Redis 的内存是有限的,当数据量超过设定的最大内存(maxmemory)时,就需要触发 内存淘汰策略 来删除部分数据,从而为新数据腾出空间。

Redis 提供了多种内存淘汰算法,主要可以归纳为以下四类:


1. 随机淘汰(Random)

  • 策略说明:当内存不足时,Redis 会随机选择并移除一个 key。

  • 优点:实现简单,开销极低。

  • 缺点:完全随机,可能会淘汰掉热门数据,对缓存命中率影响较大。

  • 适用场景:数据价值相对均等、无明显热点的数据场景。


2. TTL 淘汰(Expire)

  • 策略说明:只从设置了过期时间的 key 中挑选即将过期的 key 删除,优先清理快要过期的缓存。

  • 优点:能够优先释放掉“寿命快结束”的数据,合理性较强。

  • 缺点:如果大部分 key 没有设置 TTL,则效果有限。

  • 适用场景:业务中大量数据都带有过期时间(如会话、临时 Token)的情况。


3. LRU(Least Recently Used,最近最少使用)

  • 策略说明:淘汰最近最少访问的 key。

  • 实现机制

    • Redis 并非严格的 LRU,而是采用 近似 LRU 算法

    • 内部维护一个候选池(默认大小 16),随机挑选若干 key(默认 5 个)放入池中,再淘汰其中最久未访问的一个。

  • 优点:能较好地保留近期热点数据,提升缓存命中率。

  • 缺点:存在“热点重现”问题。如果一个长期未访问的 key 突然被访问,它会被 Redis 当成热点,从而延迟淘汰。

  • 适用场景:热点数据占比较大,但访问模式不固定的业务。


4. LFU(Least Frequently Used,最近最少使用频率)

  • 策略说明:淘汰访问频率最低的 key。Redis 从 4.0 版本开始支持。

  • 实现机制

    • 每个 key 都维护一个访问计数器,初始值为 1。

    • 每次访问 key 时,计数器递增。

    • 为避免计数器“无限增大”而导致数据长期无法淘汰,Redis 会对计数器进行 时间衰减:如果一段时间没有被访问,计数会逐渐降低。

  • 优点:比 LRU 更准确地保留真正的热点数据。

  • 缺点:实现复杂度和维护开销比 LRU 高。

  • 适用场景:热点数据稳定存在(如推荐系统、商品缓存),需要尽量提高缓存命中率的业务。


5. 如何选择合适的策略?

Redis 默认配置下不会启用淘汰策略(即 noeviction,达到内存上限后直接报错),因此在生产环境中通常需要主动设置合适的策略:

  • 随机淘汰:适合无明显热点、数据价值差不多的场景。

  • TTL 淘汰:适合大量临时数据(如 Session 缓存)。

  • LRU:适合大多数通用缓存场景,性能与命中率兼顾。

  • LFU:适合数据访问频率差异显著,且对命中率要求极高的场景。

可以通过 redis.conf 或命令行配置内存淘汰策略:

# 查看当前内存淘汰策略
CONFIG GET maxmemory-policy  

# 设置为 LRU 策略
CONFIG SET maxmemory-policy allkeys-lru

总结

Redis 提供了多种内存淘汰策略,分别适应不同的业务场景:

  • Random:效率高但命中率低;

  • Expire:依赖过期时间;

  • LRU:通用、性能好,但可能误判热点;

  • LFU:最智能,但开销最大。

在实际应用中,最常见的选择是 allkeys-lruallkeys-lfu,具体取决于业务的访问模式和命中率要求。


网站公告

今日签到

点亮在社区的每一天
去签到