Redis 内存回收策略
Reids 所有的数据都是存储在内存中的,在某些情况下需要对占用的内存空间进行回收,内存回收主要分为两类:
- key 过期删除策略
- 内存淘汰回收策略
Key 过期删除策略
- 定时过期(主动淘汰)
每个设置过期时间的 key 都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的 CPU 资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。 - 惰性过期(被动淘汰)
只有当访问一个 key 时,才会判断该 key 是否已过期,过期则清除。该策略可以最大化地节省 CPU 资源,却对内存非常不友好。极端情况可能出现大量的过期 key 没有再次被访问,从而不会被清除,占用大量内存。第二种情况,每次写入 key 时,发现内存不够,调用 activeExpireCycle 释放一部分内存。 - 定期过期
每隔一定的时间,会扫描一定数量的数据库的 expires 字典中一定数量的 key,并清除其中已过期的 key。如果有超过25%的key过期,那么会不断重复过期检测,直到过期的keys的百分比低于25%。这意味着,在任何给定的时刻,最多会清除1/4的过期keys。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得 CPU 和内存资源达到最优的平衡效果。
Redis 中同时使用了惰性过期和定期过期两种过期策略。
内存淘汰回收策略
Redis 的内存淘汰策略,是指当内存使用达到最大内存极限时,需要使用淘汰算决定清理掉哪些数据,以保证新数据的存入。
maxmemory-policy noeviction
策略 | 含义 |
noeviction | 默认策略,不会删除任何数据,拒绝所有写入操作并返回客户端错误信息 |
volatile-lru | 根据 LRU 算法删除设置了超时属性(expire)的键,直到腾出足够内存为止。如果没有可删除的键对象则回退到 noeviction 策略 |
allkeys-lru | 根据 LRU 算法删除键,不管数据有没有设置超时属性,直到腾出足够内存为止 |
volatile-lfu | 在带有过期时间的键中选择最不常用的 |
allkeys-lfu | 在所有的键中选择最不常用的,不管数据有没有设置超时属性 |
volatile-random | 在带有过期时间的键中随机选择 |
allkeys-random | 随机删除所有键,直到腾出足够内存为止 |
volatile-ttl | 根据键值对象的 ttl 属性,删除最近将要过期数据。如果没有,回退到 noeviction 策略 |
LRU 算法:最近最少使用的
LFU 算法:使用频率最低的