热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

LRU(leastrecentlyused)算法浅析

LRU(Leastrecentlyused)算法,顾名思义:最近最少使用。LRU-1算法算法根据数据的历史访问记录来进行淘汰

LRU(Least recently used)算法,顾名思义:最近最少使用。

  1. LRU-1算法

    算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。最常见的实现是使用一个链表保存缓存数据,如下图所示:

    在这里插入图片描述
    这个链表即是我们的缓存结构,缓存处理步骤为:

    1)、初始化一个定长的链表,用于表示缓存数据组成;

    2)、当请求进来时,进行缓存,并按请求的先后顺序,加入到链表中,先加入的在底部,后加入的在顶部,重复的请求从链表尾部升至顶部;(最新被访问的数据相对其他数据来说可能是热点数据,具有保留时间更久的意义)

    3)、当链表数据放满时,仍有新请求进来,且没有命中缓存,则先将底部的数据淘汰,也就是清除不常访问的数据,再将新数据缓存,加入到链表顶部。

  2. LRU-K算法

    其实上面的算法只是LRU算法中的特例情况即LRU-1,其中存在较多不合理性,在实际应用过程中会对该算法进行改进,例如偶然的数据影响会造成命中率较低,比如某个数据即将到达底部即将被淘汰,但由于一次请求又放入了头部,此后再无该数据的请求,那么该数据的继续存在其实是不合理的。针对这类情况,LRU-K算法拥有更好的解决措施。结构图如下所示:

    在这里插入图片描述
    LRU-K需要多维护一个队列或者更多,用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候,才将数据放入缓存。当需要淘汰数据时,LRU-K会淘汰第K次访问时间距当前时间最大的数据。

    1)、历史访问队列
    将最新请求的数据放在历史访问队列头部,该队列遵循先进先出原则。(队列长度根据系统QPS来定)
    每次有数据加入到队列中时,若队列已满,则从尾部淘汰数据,未满,则直接加在队列头部。再统计当前队列中当前数据在队列中出现的次数,若达到K次,则将它加入到接下来的2级(具体需要几级结构也同样结合系统分析)链表中,按照最新访问时间顺序在2级链表中排列。

    2)、2级链表
    同上LRU-1算法,链表中的数据如果再次被访问,则移到头部,链表满时,底部数据淘汰。

    相比LRU,LRU-K需要多维护一个队列,用于记录所有缓存数据被访问的历史,所以需要更多的内存空间来用来构建缓存,但优点也很明显,较好的降低了数据的污染率提高了缓存的命中率,对于系统来说可以用一定的硬件成本来换取系统性能也不失为一种办法。

  3. 折衷方案

    针对LRU-1和LRU-K有一种折衷的方案,引入权重来实现在有限资源情况下的合理缓存。

    1)、初始化一个队列,用于表示缓存数据组成;

    2)、当新请求(未命中缓存)进来时,进行缓存,设定权重为当前队列中所有数据权重的中位数,并对队列进行重新排序;当请求进来(命中缓存时),对该数据权重+n,并对队列进行重新排序。

    3)、当队列达到指定长度时,仍有新请求进来,且没有命中缓存,则先将底部的数据淘汰,也就是清除不常访问的数据,再执行第2步。

    该方案的重点在于合理设置重新访问的权重n。


推荐阅读
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 深入理解一致性哈希算法及其应用
    本文详细介绍了分布式系统中的一致性哈希算法,探讨其原理、优势及应用场景,帮助读者全面掌握这一关键技术。 ... [详细]
  • 深入解析TCP/IP五层协议
    本文详细介绍了TCP/IP五层协议模型,包括物理层、数据链路层、网络层、传输层和应用层。每层的功能及其相互关系将被逐一解释,帮助读者理解互联网通信的原理。此外,还特别讨论了UDP和TCP协议的特点以及三次握手、四次挥手的过程。 ... [详细]
  • FinOps 与 Serverless 的结合:破解云成本难题
    本文探讨了如何通过 FinOps 实践优化 Serverless 应用的成本管理,提出了首个 Serverless 函数总成本估计模型,并分享了多种有效的成本优化策略。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • 本文介绍了Linux系统中的文件IO操作,包括文件描述符、基本文件操作函数以及目录操作。详细解释了各个函数的参数和返回值,并提供了代码示例。 ... [详细]
  • 本文探讨了 Swapper 工具对系统内存和存储设备(如 SD 卡)的潜在影响,解释其工作原理及使用时需要注意的问题。 ... [详细]
  • 本文详细介绍了 RosPack 类的功能和用法,探讨了其在 ROS 系统中的重要作用。RosPack 类提供了类似于终端命令 rospack 的功能,能够方便地查询和管理 ROS 包的相关信息。 ... [详细]
  • MySQL 高性能实战教程
    本课程深入探讨 MySQL 的架构、性能调优、索引优化、查询优化及高可用性等关键领域。通过实际案例和详细讲解,帮助学员掌握提升 MySQL 数据库性能的方法与技巧。 ... [详细]
author-avatar
sjf66355555
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有