如果Redis中数据非常多,将服务器中的内存都耗尽,这样就会出现内存溢出的情况,Redis开发组考虑到了这种问题,使用数据淘汰策略可以解决这个问题。
可以设置内存最大使用量,当内存使用量超出时,会施行数据淘汰策略。
Redis 具体有 6 种淘汰策略:
策略 | 描述 | 应用场景 |
---|---|---|
volatile-lru | 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰 | 如果设置了过期时间,且分热数据与冷数据,推荐使用 volatile-lru 策略。 |
volatile-ttl | 从已设置过期时间的数据集中挑选将要过期的数据淘汰 | 如果让 Redis 根据 TTL 来筛选需要删除的key,请使用 volatile-ttl 策略。 |
volatile-random | 从已设置过期时间的数据集中任意选择数据淘汰 | 很少使用 |
allkeys-lru | 从所有数据集中挑选最近最少使用的数据淘汰 | 使用 Redis 缓存数据时,为了提高缓存命中率,需要保证缓存数据都是热点数据。可以将内存最大使用量设置为热点数据占用的内存量,然后启用 allkeys-lru 淘汰策略,将最近最少使用的数据淘汰。 值得一提的是,设置 expire 会消耗额外的内存,所以使用 allkeys-lru 策略,可以更高效地利用内存,因为这样就可以不再设置过期时间了。 |
allkeys-random | 从所有数据集中任意选择数据进行淘汰 | 如果需要循环读写所有的key,或者各个key的访问频率差不多,可以使用 allkeys-random 策略 |
noeviction | 不删除策略,达到最大内存限制时,如果需要更多内存,直接返回错误信息。大多数写命令都会导致占用更多的内存 | 很少使用 |
作为内存数据库,出于对性能和内存消耗的考虑,Redis 的淘汰算法实际实现上并非针对所有 key,而是抽样一小部分并且从中选出被淘汰的 key。
Redis 4.0 引入了 volatile-lfu 和 allkeys-lfu 淘汰策略,LFU 策略通过统计访问频率,将访问频率最少的键值对淘汰。
您需要根据系统的特征,来选择合适的淘汰策略。 当然,在运行过程中也可以通过命令动态设置淘汰策略,并通过 INFO 命令监控缓存的 miss 和 hit,来进行调优。
淘汰策略的内部实现
- 客户端执行一个命令,导致 Redis 中的数据增加,占用更多内存
- Redis 检查内存使用量,如果超出 maxmemory 限制,根据策略清除部分 key
- 继续执行下一条命令,以此类推
在这个过程中,内存使用量会不断地达到 limit 值,然后超过,然后删除部分 key,使用量又下降到 limit 值之下。
如果某个命令导致大量内存占用(比如通过新key保存一个很大的set),在一段时间内,可能内存的使用量会明显超过 maxmemory 限制。