可以看到上面回收策略有俩个纬度,
然后基于上面俩种纬度,做个组合就是四种主要策略。
需要注意的这里提到的过期集合,翻译并不是特别准确。它并不是指的这些键是已经过期了,而是指存放着含有过期时间的键;如果一个键没有过期时间,那么就不会存在在该集合中。redis中可以对键设置过期时间,只要是设置了过期时间的键都会存放在redis中专门的一个数据结构。
lru淘汰的主要执行逻辑是在方法freeMemoryIfNeeded(void) 。在方法执行期间,客户端发出的命令会被阻塞住。阻塞命令执行也是为了避免更多的内存被使用。
算法主要逻辑:
do
{
for(db in dbs)
{
根据配置的淘汰策略
选择最适合的key
释放资源
}
}while(freed < tofreed)//已经释放的小于需要释放的
选择最合适的key这一步操作就要结合上面所说的,redis设置的几种淘汰策略。根据redis设置的淘汰策略,选择出需要淘汰的key,然后通过key释放起资源。
需要注意的是在这里的lru也不是严格的lru算法,它是基于一个配置的大小值maxmemory_samples,循环遍历samples,随机获取key然后找到一个最合适的key,然后把该key删除掉。网上也有文章分析,在这种类lru算法下,基本和真正的lru算法的性能没有太大差异,但是相比较于真正严格的lru效率要更高。
判断那个key是最合适是通过比较该key的lru时间和sever里维护的lru_clock差值。server.lruclock在定时事件中会被定时循环更新,会更新成和当前时钟值有个倍数关系的值。
/* Given an object returns the min number of seconds the object was never
* requested, using an approximated LRU algorithm. */
unsigned long estimateObjectIdleTime(robj *o) {
if (server.lruclock >= o->lru) {
return (server.lruclock - o->lru) * REDIS_LRU_CLOCK_RESOLUTION;
} else {
return ((REDIS_LRU_CLOCK_MAX - o->lru) + server.lruclock) *
REDIS_LRU_CLOCK_RESOLUTION;
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。