1.删除策略
定期删除
每隔一段时间就扫描一定数据的设置了过期时间的key,并清除其中已过期的keys。如果有多于25%的key过期,重复上述步骤。
惰性删除
访问key时判断是否过期,过期才删除。也就是说如果这个key过期后一直没有访问它,那么它就一直在不会被删除。
2.淘汰策略
1.noeviction(默认策略): 不会删除任何数据,拒绝所有写入操作并返回客户端错误消息(error)OOM command not allowed when used memory,此时 Redis 只响应删和读操作;
2.allkeys-lru: 从所有 key 中使用 LRU 算法进行淘汰(LRU 算法:最近最少使用算法);
3.allkeys-lfu: 从所有 key 中使用 LFU 算法进行淘汰(LFU 算法:最不常用算法,根据使用频率计算,4.0 版本新增);
4.volatile-lru: 从设置了过期时间的 key 中使用 LRU 算法进行淘汰;
5.volatile-lfu: 从设置了过期时间的 key 中使用 LFU 算法进行淘汰;
6.allkeys-random: 从所有 key 中随机淘汰数据;
7.volatile-random: 从设置了过期时间的 key 中随机淘汰数据;
8.volatile-ttl: 在设置了过期时间的key中,淘汰过期时间剩余最短的。
淘汰算法
1.全局时钟
struct redisServer {
pid_t pid;
char *configfile;
//全局时钟
unsigned lruclock:LRU_BITS;
...
};
Redis维护了一个24位时钟,前16位还代表时钟,后8位代表一个计数器
2.Redis LRU 算法(时间算法)
Redis 在每个数据对象 RedisObject 中存放 lru 字段,表示该数据最近一次访问的时间戳,以后做数据淘汰时用该字段作为比较依据。
当执行数据淘汰时, 首次 执行将按以下步骤选择数据:
1、随机 选出 N (maxmemory-samples)个数据,把它们作为一个候选集合;
2、比较这 N 个数据的 lru 字段,把 lru 字段值最小的数据淘汰出去;
3.Redis LFU 算法(次数算法)
LRU 算法存在一个缺陷,因为它 只关心数据的访问时间,在发生扫描式单次查询操作时,所有的数据都会被访问一次,这样可能导致很多热数据反而被排到了 LRU 的末端而被淘汰。
针对这个问题,LFU 缓存策略 在 LRU 策略基础上,为每个数据 增加了一个计数器,来统计这个数据的访问次数。当使用 LFU 策略筛选淘汰数据时:
1、首先根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出去;
2、如果两个数据的访问次数相同,再比较两个数据的访问时效性,把距离上一次访问时间更久的数据淘汰出去。
因此,LFU 算法会将访问更频繁的数据保留,而优先淘汰访问次数最少的数据,在访问次数相当的情况下再选择访问时间最久远的数据淘汰。