Redis里那些淘汰策略到底咋选,全面聊聊各种情况和适用场景
- 问答
- 2025-12-31 04:55:03
- 5
聊到Redis的淘汰策略怎么选,这确实是个挺实际的问题,你不能光知道Redis能缓存东西,还得知道当内存快满的时候,它怎么“丢东西”来腾地方,这个“丢东西”的规则,就是淘汰策略,选错了,可能你最重要的数据就被扔掉了,缓存的效果大打折扣。
Redis提供了8种策略,但我们可以把它们归为几大类,这样好理解。

第一类:不淘汰,直接报错。 这就是 noeviction 策略,当内存不够用来写新数据时,Redis就直接返回一个错误,拒绝执行新的写入命令(读操作正常),这是Redis的默认策略。
- 适用场景:如果你的系统对数据的一致性要求极高,绝对不能丢失任何已经写入缓存的数据,或者你确信你的缓存大小永远不可能超过内存上限(比如有完善的监控和扩容机制),那么可以用这个,但说实话,大多数业务场景下,我们宁愿丢掉一些旧数据,也不希望整个写服务挂掉,所以这个策略用得不多。
第二类:在设置了过期时间的数据里淘汰。 这类策略只会在那些你明确设置了过期时间(TTL)的键里进行筛选和删除。

- volatile-ttl:优先淘汰剩余存活时间最短的键,它觉得快过期的数据反正马上也要没了,不如先扔掉。
- 适用场景:你希望尽可能让那些还能活很久的热点数据留在缓存里,比如一些热点新闻的缓存,设置了一小时过期,那么即将到一小时的就先淘汰掉,让新来的、更热的新闻进来。
- volatile-random:在设置了过期时间的键里,随机挑一个扔掉,简单粗暴,没啥计算开销。
- 适用场景:当你觉得所有带过期时间的数据重要性都差不多,没有明显的热点冷门之分,用这个最省事,但风险是可能随机到某个还挺重要的数据。
- volatile-lru:在设置了过期时间的键里,淘汰最近最少使用的键,这是最常用的策略之一,LRU算法的核心思想是“如果某个数据最近被用过,那么它将来被用到的可能性也更大”,所以它会优先干掉那些最久没被访问的数据。
- 适用场景:这是非常普适的策略,如果你的业务有明显的热点数据(比如电商网站的头条商品),这些数据会被频繁访问,而冷门数据很久没人看,用volatile-lru能很好地保护热点数据不被淘汰,比如你缓存了用户会话(session),活跃用户的会话总被访问,就不会被淘汰,而不活跃用户的会话就会被清理掉。
- volatile-lfu:在设置了过期时间的键里,淘汰最不经常使用的键,LFU是LRU的改进版,它看的不是“最近一次使用的时间”,而是“一段时间内使用的频率”,一个键被访问的次数越多,频率就越高。
- 适用场景:适用于访问频率差距非常大的场景,有一个爆款商品,一天被访问上百万次,而普通商品只有几百次,LFU能非常精准地识别并保留这种“超级热点”,即使这个爆款商品有一小段时间没人看,它的高频率历史记录也能保护它不被轻易淘汰,而LRU可能因为一个偶然的、长时间不访问而被误伤。
第三类:在所有数据里淘汰(包括没设置过期时间的)。 这类策略范围更广,不管你有没有设置过期时间,只要在内存里,就是候选目标。
- allkeys-lru:从所有键中淘汰最近最少使用的。
- 适用场景:这是另一个极其常用的策略,甚至比volatile-lru更普遍,因为很多时候,我们缓存的全部数据都可以被淘汰,没有说哪些数据必须永久留在内存里(永久数据应该存数据库),在这种情况下,allkeys-lru能最大化缓存的效率,确保整个内存空间里存放的都是最热门的数据,比如你的Redis实例只做缓存用,里面所有数据在数据库都有备份,那就大胆用这个。
- allkeys-random:从所有键中随机淘汰。
- 适用场景:和volatile-random类似,适用于所有数据重要性都差不多的场景,但同样有误伤风险,用得比较少。
- allkeys-lfu:从所有键中淘汰最不经常使用的。
- 适用场景:和volatile-lfu思想一样,只是范围扩大到全部数据,当你需要在整个数据集中保护访问频率最高的核心热点时,用这个,比如一个推荐系统,需要确保最常被推荐的那些物品的画像数据永远在缓存里。
到底怎么选?简单总结一下:
- 如果你的数据分两种:一些是重要的、不能丢的(即使设置了过期时间),另一些是纯粹的缓存可以丢。 那么选 volatile-lru 或 volatile-lfu,这样能保证那些重要数据(只要不过期)不会被淘汰策略误删。
- 如果你的Redis实例完全当作缓存来用,所有数据都能从数据库重新加载。 这是最常见的情况,强烈推荐使用 allkeys-lru,它能智能地保持内存里都是热数据,缓存命中率最高。
- 如果你能明确预知数据的访问频率,且频率差距很大。 比如你有少数几个“爆款”,需要极致地保护它们,那就选择 allkeys-lfu(或volatile-lfu,根据你的数据性质定)。
- 如果你对数据访问模式没啥概念,就是平均访问。 可以用 ...-random,但更稳妥的还是用 ...-lru,因为它通常能提供还不错的性能。
- 除非你有十足的把握和严密的监控,否则尽量不要用 noeviction。 因为写失败可能会引起上游服务雪崩。
最后记住一点,LRU/LFU在Redis中都不是完全精确的实现,而是基于采样的近似算法(为了节省内存和提高速度),但这对绝大多数应用来说已经完全足够了,选择策略的核心在于了解你的数据访问模式,知道哪些数据更“重要”,然后选择一个能保护重要数据的规则。
本文由帖慧艳于2025-12-31发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/71684.html
