Redis里头那个淘汰机制到底是咋回事,怎么影响数据存储和性能的呢?
- 问答
- 2025-12-29 23:31:48
- 2
关于Redis的淘汰机制,说白了就是当它的内存快要用完的时候,它不得不做出一个艰难的决定:扔掉一些数据,以便腾出地方给新来的数据,你可以把它想象成一个容量有限的仓库,当新货不断运进来,仓库快要堆满时,管理员就必须根据一套事先定好的规则,决定把哪些旧货清理出去,这套规则,就是Redis的淘汰策略。
为什么需要这个机制?
这得从Redis的设计初衷说起,Redis的核心优势就是快,而它之所以快,一个重要原因是所有数据都放在内存里,内存的读写速度远超硬盘,但问题是内存的成本高,容量有限,不像硬盘可以轻易地扩展到几个T,服务器的内存大小通常是固定的,比如16G、32G,如果Redis放任数据无限制地写入,总有一天会把内存撑爆,导致Redis服务崩溃,无法再写入任何新数据,甚至可能影响整个服务器的稳定。
这个淘汰机制不是一个可选功能,而是一个必要的“安全阀”,它确保Redis在内存资源紧张的情况下,依然能继续提供服务,而不是直接“罢工”。
淘汰机制是如何工作的?(来源:Redis官方文档关于maxmemory-policy的说明)

这个机制的核心由一个关键配置项控制:maxmemory-policy,这个配置项就是你告诉Redis的“清理规则”,当Redis占用的内存量达到了你设定的上限(通过maxmemory参数配置),每当有新的数据需要写入,或者某个命令导致内存用量增加时,Redis就会执行一次淘汰逻辑,根据你设定的策略,尝试移除一个或多个键,直到有足够的空间容纳新数据为止。
常见的淘汰策略及其影响(来源:基于Redis官方文档对各类策略的解释和社区实践讨论)
Redis提供了大约八种策略,可以分为两大类:“不淘汰”和“淘汰”,我们挑几个最常用、最有代表性的来说说:
-
noeviction(不淘汰): 这是老版本Redis的默认策略,它的行为最简单粗暴:当内存不够时,所有会导致增加内存使用的写命令(比如
SET,LPUSH等)直接报错,读命令不受影响,这就像仓库管理员两手一摊,说“没地儿了,新货别送了”,这个策略能保证已有的数据绝对不会被误删,但代价是服务的可用性受损,客户端会收到错误,如果你的数据至关重要,宁可暂时不能写入也绝不能丢失,可以考虑这个策略。
-
allkeys-lru(全体键的LRU): 这是目前比较流行和通用的策略,LRU是“最近最少使用”的缩写,Redis会尝试淘汰掉全体键中那个最长时间没有被访问过的键,它基于一个假设:最近被访问过的数据,将来也更有可能被访问,这很像我们生活中整理书桌,会把最近没看过的书收起来,这个策略的好处是能比较智能地保留热点数据,把“冷”数据清理掉,但它也有开销,Redis需要维护一个近似LRU的列表来跟踪访问情况,虽然已经做了优化,但相比一些简单策略,还是会消耗一点点CPU。
-
volatile-lru(带过期时间的键的LRU): 这个策略和上面的
allkeys-lru很像,区别在于它只会在那些设置了过期时间(TTL)的键中间进行淘汰,而没设置过期时间的键会被认为是永久数据,受到保护,不会被淘汰,这适用于你把Redis既当缓存用(数据可丢,设TTL),又当持久化存储用(数据不可丢,不设TTL)的场景,它能保证你的核心数据安全,只清理缓存数据。 -
allkeys-random(全体键随机): 顾名思义,就是从所有的键中随机选择一个淘汰掉,这个策略的实现非常简单,速度极快,几乎不消耗额外CPU,但它的缺点也很明显:它完全不管这个数据是不是热点数据,有可能一不小心就把一个经常被访问的“爆款”数据给删了,这可能会立刻影响应用性能,因为下次请求这个数据时就得去慢速的数据库重新加载。
-
volatile-ttl(按过期时间淘汰): 这个策略只在设置了过期时间的键中生效,它会优先淘汰掉剩余存活时间最短的键,这非常符合缓存的直觉:“反正你马上就要过期了,不如早点让你走,给新数据腾地方”,这个策略在缓存场景下非常高效。

对数据存储和性能的具体影响
-
对数据存储的影响: 最直接的影响就是数据丢失,只要你选择了“淘汰”类的策略(除了
noeviction),就必须要接受Redis可能会自动删除你的数据这个事实,你绝对不能把Redis当作唯一的数据源来存储你无法重建的重要数据,它更像是一个前端缓存或者临时工作区,策略的选择决定了丢失哪些数据:是可能丢失任何数据(allkeys-*),还是只丢失缓存数据(volatile-*);是丢失最不活跃的数据(LRU),还是无差别丢失(随机)。 -
对性能的影响:
- 正面影响: 最大的正面影响是避免了服务中断,如果没有淘汰机制,内存写满后Redis就可能崩溃,重启和恢复过程会造成更长时间的服务不可用,淘汰机制通过有代价的牺牲(删除部分数据),换来了整体的服务可用性。
- 负面影响: 主要是额外的CPU开销和潜在的延迟波动,执行淘汰策略本身需要计算,比如LRU算法需要维护和更新访问记录,这会消耗CPU资源,更重要的是,淘汰动作发生在写入命令的过程中,当内存已满,客户端执行一个写命令,Redis必须先“现场”执行淘汰逻辑,腾出空间,才能完成这个写操作,这个淘汰过程会阻塞当前的命令请求,导致该请求的响应时间变长,出现延迟毛刺,如果一次性需要淘汰很多数据才能满足要求,这个延迟可能会非常明显。
总结一下
Redis的淘汰机制是一个在内存资源有限前提下,平衡数据保留和服务可用性的关键设计,你需要根据你的业务场景仔细选择策略:如果你的数据完全不可丢失,就用noeviction但得承受写失败的风险;如果Redis主要用作缓存,希望自动保留热点数据,allkeys-lru是个好选择;如果你的数据有明确的生命周期,volatile-ttl可能更高效,理解这些策略的原理和代价,对于稳定、高效地使用Redis至关重要。
本文由符海莹于2025-12-29发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/70930.html
