目录
我们都知道Redis速度飞快,一个重要原因是它的数据都放在内存里。但内存是有限的,当Redis的内存被占满后,新的写入请求就会报错。这显然不行!
那么,Redis是如何聪明地解决这个问题的呢?答案就在于其核心的删除策略。它决定了在内存不足时,哪些数据该被优先淘汰,从而为新的数据腾出空间。
Redis的删除策略主要分为两类:
1. 定期删除:主动的“日常清扫”
想象一下你有一个会自动整理的房间。Redis会定期地、随机地检查一些设置了过期时间的key(TTL),如果发现某个key已经过期了,就立刻删除它。
- 优点:通过分散式的检查,降低了CPU的压力,避免了一次性检查所有key带来的卡顿。
- 缺点:由于是随机抽样,不可能清除掉所有过期的key,总会有些“漏网之鱼”持续占用着内存。
这就引出了第二个策略。
2. 惰性删除:被动的“用的时候再说”
即使有了定期清理,还是会有一些过期的key没被及时删掉。惰性删除扮演了“守门员”的角色:只有当客户端试图访问一个key时,Redis才会检查它是否已过期。如果过期了,就立刻删除这个key并且返回空值。
- 优点:对CPU最友好,只在必要时才付出删除的成本。
- 缺点:如果大量过期的key永远不再被访问,它们就会成为“垃圾数据”,永远无法被释放,造成内存浪费。
定期删除 + 惰性删除 组合拳是Redis处理过期key的主要方式。但这两种策略都只针对有过期时间的key。
3. 内存淘汰:最终的“强制手段”
当内存耗尽,所有写入操作(SET
, LPUSH
等)都会触发错误。为了防止这种情况,我们必须配置 maxmemory-policy
,即内存淘汰策略。这才是决定“内存满了,谁先走”的终极规则。
Redis提供了8种策略,可分为几类:
1.对全部数据:
noeviction
(默认):不淘汰。直接返回错误。生产环境慎用!allkeys-lru
:全体集合,淘汰最近最少使用的。这是最常用的策略。allkeys-random
:全体集合,随机淘汰。
2.仅对设置了过期时间的数据:
volatile-lru
:从过期集合中,淘汰最近最少使用的。volatile-random
:从过期集合中,随机淘汰。volatile-ttl
:从过期集合中,淘汰存活时间(TTL)最短的。volatile-lfu
/allkeys-lfu
:淘汰最不经常使用的(4.0+版本支持)。
如何选择?
- 如果你的数据访问模式有热点,部分数据更常用,选择
allkeys-lru
准没错。 - 如果你希望不同类型的数据有不同的淘汰规则,可以使用
volatile-*
策略,并为关键数据不设置TTL,使其永不被淘汰。 - 如果你只是想把Redis当作一个纯缓存,所有数据都可以丢弃,那么
allkeys-lru
或allkeys-random
都是不错的选择。
总结
策略类型 |
工作时机 |
目标 |
特点 |
定期删除 |
定期随机检查 |
清理过期Key |
减少CPU压力,但清理不彻底 |
惰性删除 |
访问Key时 |
清理过期Key |
节省CPU,但可能积累垃圾数据 |
内存淘汰 |
内存不足时 |
腾出内存空间 |
决定数据去留的最终法则,需主动配置 |
理解并合理配置这些策略,通常,配置好 maxmemory
和 maxmemory-policy allkeys-lru
,就为你的Redis服务上了一道重要的保险。