Redis 缓存淘汰机制 :LRU 淘汰

  • U),但仅限于在过期集合的键,使得新添加的数据有空间存放。
  • volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
  • volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

可以看到上面回收策略有俩个纬度,

  1. 回收的键的范围
  2. 过期集合
  3. 不区分是过期集合
  4. 回收策略
  5. 随机
  6. 基于lru

然后基于上面俩种纬度,做个组合就是四种主要策略。

需要注意的这里提到的过期集合,翻译并不是特别准确。它并不是指的这些键是已经过期了,而是指存放着含有过期时间的键;如果一个键没有过期时间,那么就不会存在在该集合中。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;
    }
}

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程

用python搭个web服务器玩玩(一)

如果你想成为一个优秀的开发者,你应该对日常使用的软件系统的内部结构有深入的理解,包括编程语言、数据库及操作系统、Web 服务器及 Web 框架。而且,为了更好更...

2249
来自专栏coding for love

从输入url到看到页面的过程分析

我思考了很多知识组织方法来帮助理解网络知识,比如按osi模型从底至上,或者按协议种类,或者按网络发展史。但最终我还是决定选择用这个经典的问题,将网络知识串成线。...

752
来自专栏张善友的专栏

Code-First Migrations随Entity Framework 4.3一同发布

Entity Framework 4.3 版本终于为开发者带来了迁移(Migrations)功能,从此以后使用EF不必依赖于单独预发布的迁移库了。 什么是EF迁...

1729
来自专栏后台全栈之路

U-Boot 中添加自定义网络通信的方法

U-boot 没有 TCP 协议栈,不支持 TCP(提出要在 U-boot 里面支持 TCP 的协议的 PM 你给我出去)。但是UDP 还是有的。使用 U-bo...

1228
来自专栏java架构学习交流

Java web开发,在一个jsp里放太多java代码的后果,摘自 java web轻量级开发面试教程

现要做一个简单的登录页面,如果用户通过验证,会显示Welcome用户名的欢迎词,反之则返回登录页面让用户再次输入 这部分的完整代码是JSPDemo项目里的log...

2037
来自专栏Java帮帮-微信公众号-技术文章全总结

Java企业面试——Javaweb

2.Javaweb阶段 2.1 Ajax你以前用过么?简单介绍一下 AJAX = 异步 JavaScript 和 XML。 AJAX 是一种用于创建快速...

3408
来自专栏程序猿DD

从零开始的Spring Session(二)

上一篇文章 从零开始的Spring Session(一) 中介绍了一些Session和Cookie的基础知识,这篇文章开始正式介绍Spring Session是...

1979
来自专栏北京马哥教育

深入浅出:Linux设备驱动之中断与定时器

“我叮咛你的 你说 不会遗忘 你告诉我的 我也全部珍藏 对于我们来说 记忆是飘不落的日子 永远不会发黄 相聚的时候 总是很短 期待的时候 总是很长 岁月的溪水边...

2649
来自专栏java一日一条

Spring Boot + Mybatis + Redis二级缓存开发指南

Spring-Boot因其提供了各种开箱即用的插件,使得它成为了当今最为主流的Java Web开发框架之一。Mybatis是一个十分轻量好用的ORM框架。Red...

793
来自专栏程序员互动联盟

【编程基础】Windows下如何玩转串口编程

问题:有朋友在群里问Windows下如何给单片机发送或者接收数据。 ? 在windows下,各种外设都被看成文件,这个跟Linux下看成设备节点类似,所以串...

2845

扫码关注云+社区