一、Redis的内存淘汰机制(当内存不足以容纳新入数据时)
打开redis.conf文件可知,redis5以后的版本一共支持8种内存淘汰策略
淘汰范围:
allkeys-xxx:allkeys开头的是对Redis中的所有key都在淘汰范围内。
volatile-xxx:volatile开头的是对Redis中的设置了超时时间的key列入淘汰范围。
策略 | 淘汰范围 | 含义 |
---|---|---|
noeviction | 当内存不足以容纳新入数据时,新写入操作就会报错,采用no-enviction策略可以保证数据不被丢失 | |
volatile-lru | 设置了过期时间的key | 挑选使用次数最少的数据淘汰(按访问次数) |
volatile-lfu | 设置了过期时间的key | 挑选使用频率最低的数据淘汰(按访问频率) |
volatile-random | 设置了过期时间的key | 随机选择数据淘淘 |
volatile-ttl | 设置了过期时间的key | 根据过期时间淘汰,越早过期越早淘汰 |
allkeys-lru | 所有key | 挑选使用次数最少的数据淘汰(按访问次数)(这个比较常用) |
allkeys-lfu | 所有key | 挑选使用频率最低的数据淘汰(按访问频率) |
allkeys-random | 所有key | 随机选择数据淘淘 |
算法 | 含义 |
---|---|
ttl | 设置了过期时间的key中,剩余时间更少的优先淘汰。 |
lru | 最近最少使用的key,优先被淘汰。 |
lfu | 最近访问频率最少的key,优先被淘汰。 |
random | 随机淘汰内存中内容。 |
noeviction | 无法再写入Redis,不会处理内存中的内容,是默认的淘汰策略。 |
二、Redis的过期策略(惰性删除+定期删除)
前面介绍的都是在Redis内存占用满的情况下的淘汰策略,那么当内存没占满时在Redis中过期的key是如何从内存中删除以达到优化内存占用的呢?
官网:https://redis.io/commands/expire#expire-accuracy
在Redis中过期的key不会立刻从内存中删除,而是会同时以下面两种策略进行删除:
- 惰性删除:
当key被访问时检查该key的过期时间,若已过期则删除,返回null;优点对CPU友好,缺点已过期未被访问的数据仍保持在内存中,消耗内存资源; - 定期删除:
每隔一段时间,随机检查设置了过期时间的key并删除已过期的key;维护定时器消耗CPU资源;
Redis每10秒进行一次过期扫描:
1、随机取20个设置了过期策略的key;
2、检查20个key中过期时间中已过期的key并删除;
3、如果有超过25%的key已过期则重复第1步;
这种循环随机操作会持续到过期key可能仅占全部key的25%以下时,并且为了保证不会出现循环过多的情况,默认扫描时间不会超过25ms;