IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

标签:LRU

共 6 篇相关文章

IT 累计浏览 3,594

缓存算法–LRU

这篇讲的是两种经典的缓存淘汰算法:LRU和它的改进版LRU-K。文章开门见山,先解析了LRU(最近最少使用)的核心思想——它用一个巧妙的链表来实现,新数据插入头部,每次访问都把数据提到最前,满了就淘汰尾部那个“最久没碰”的。这种策略在热点数据集中时效率很高,实现也简单。 但文章也指出了LRU的软肋:一旦出现偶发的批量扫描,会挤掉很多热门数据,造成严重的“缓存污染”。为了解决这个问题,文章引入了LRU-K。这里的“K”代表一个访问次数阈值,比如我们常说的LRU-2。它不再因为一次访问就把数据加入缓存,而是让数据在历史队列中先“排队”,只有被访问了K次,证明它确实是热点,才获准进入缓存队列。 这样一来,LRU-K的命中率通常比LRU更高,能有效抵抗缓存污染。但天下没有免费的午餐,它的实现需要维护额外的访问历史队列并进行排序,算法复杂度、内存消耗和CPU开销都比LRU要高。文章最后也点明了选择的关键:LRU胜在简单高效,适合大多数常规场景;而当你面对严重的访问模式波动时,LRU-K(尤其是LRU-2)提供了一个更稳健的选择。

IT 累计浏览 4,266

Memcached二三事儿

这篇讲的是作为NoSQL“老兵”的Memcached。尽管Redis等后起之秀势头强劲,Memcached在许多项目中依然不可或缺。文章没有停留在“要不要学”的讨论,而是直接深入Memcached的核心——Slab内存分配机制。作者用了一个生动的比喻来解释Page、Slab和Chunk之间的关系,指出早期版本中内存无法跨Slab调配的痛点,并介绍了新版本通过slab_reassign参数实现的“Page改嫁”机制。 文章还触及了Memcached在实际应用中的典型挑战。例如,为应对缓存失效瞬间的“惊群效应”(stampeding herd),作者依次讨论了主动更新、加锁、柔性过期等方案的利弊,并最终引入了通过Gearman进行异步任务分发的更稳健的解法。此外,文中提及的Twemcache对Memcached的改进,也从侧面反映了技术在实际生产中的演进。 对仍在使用或需要深入理解Memcached原理的工程师来说,文章对内存管理细节的剖析和对常见坑点的梳理,依然具有很强的实用参考价值。

IT 累计浏览 3,070

MySQL数据库InnoDB存储引擎 Buffer Pool Flush List详解

这篇详解的是MySQL InnoDB存储引擎中Buffer Pool的Flush List机制。作者深入剖析了当数据页在Buffer Pool中被修改成脏页后,InnoDB如何通过Flush List来跟踪并最终将它们异步刷回磁盘的过程。 文章的核心在于阐明Flush List的设计与工作原理。它不是一个简单的队列,而是按照页的修改时间(最早修改时间)进行组织的链表。这个设计巧妙之处在于,它能确保最“老”的脏页被优先刷新,从而有效控制数据库恢复时间(Redo Log覆盖循环的约束),并配合Adaptive Flushing等策略,平衡刷盘对性能的影响。 通过讲解Flush List与LRU List的协同工作、刷盘时机的判断逻辑,以及它对数据库整体性能和稳定性的关键作用,文章为读者理清了InnoDB如何高效、可靠地管理内存与磁盘的数据同步。理解这部分机制,是进行MySQL深度性能优化和故障分析的重要基础。

IT 累计浏览 5,056

MySQL数据库InnoDB存储引擎 Buffer pool LRU List Flush策略详解

这篇文章深入到了MySQL InnoDB存储引擎的内存管理核心,讲的是它如何通过精心设计的LRU List和Flush List协作,来高效管理Buffer Pool这一宝贵的内存资源。作者没有停留在表面概念,而是从LRU链表的“冷热数据分离”机制讲起,剖析了young区和old区如何协作来避免全表扫描等操作对热点数据的污染。 文章的巧妙之处在于揭示了LRU与Flush两个链表的分工与协同。LRU链表负责维护数据的访问热度,决定数据页的“生杀大权”;而Flush链表则专门追踪那些被修改过但还未写入磁盘的脏页,是内存与磁盘同步的关键。通过解析这种双重链表结构与后台刷新线程的配合,文章清晰地展示了一套动态的内存管理策略:既能保证热数据的快速访问,又能异步、平滑地将脏数据刷盘,从而在性能与数据持久性之间找到最佳平衡点。 读完这篇文章,你不仅能理解Buffer Pool配置参数背后的原理,更能对InnoDB如何在高并发压力下既保持响应速度又确保数据不丢失,建立起一个扎实的认知框架。

IT 累计浏览 3,877

ConcurrentHaspLRUHashMap实现初探

这篇讲的是作者如何尝试实现一个线程安全的LRU缓存结构——ConcurrentHaspLRUHashMap。面对高并发场景下,既需要快速存取、又需要自动淘汰最久未使用数据的需求,现有的解决方案可能各有局限。作者的出发点很明确,就是探索一种能兼顾并发性能与LRU淘汰策略的全新实现。 文章的核心在于拆解这个混合结构的设计思路。它不像传统的ConcurrentHashMap那样只考虑并发存取,也不像简单的LRU列表那样忽略线程安全。作者需要在两者间找到平衡,比如如何用锁或CAS机制保证并发修改时链表顺序的正确性,又如何让哈希表与双向链表高效协作。文中可能会展示一些关键的同步控制技巧,或是性能权衡的具体考虑。 这种自定义容器的实现往往在框架或中间件中很关键。作者通过这次初探,不仅分享了具体代码,更传递了一种解决问题的思路:在复杂约束下,如何拆解需求、组合基础数据结构,并处理好并发细节。对于需要设计高性能缓存或理解Java并发容器原理的开发者来说,其中的实现考量具有直接的参考价值。

IT 累计浏览 2,772

Memcached数据被踢(evictions>0)现象分析

作者从一个常见的现象出发:为什么 Memcached 的 evictions(数据踢出)指标会一直大于 0?这通常意味着缓存的命中率可能受到影响。文章深入剖析了 Memcached 的内存管理核心——slab allocator 的工作原理。 关键点在于,Memcached 的 LRU(最近最少使用)淘汰算法是在每个独立的 slab class(内存池)内部进行的。作者用了一个很形象的比喻:可以把一个 slab 理解为一间教室,每个 chunk(数据单元)就是座位。一旦某个 slab class(教室)的所有 chunk 都被分配完毕,即使其他 slab class(其他教室)里还有空座位,当新的数据需要进入这个“满员”的 slab 时,也只能在内部通过 LRU 算法“踢掉”一个旧数据,才能腾出位置。 这个机制揭示了 Memcached 内存管理的隔离性。它能高效地为不同大小的数据分配空间,避免外部碎片。但代价是,可能出现某个 slab class 挤得满满的并频繁淘汰数据,而另一个 slab class 却相对空闲的情况。这种“局部性”正是导致 evictions > 0 的根本原因。 文章没有停留在现象解释,而是进一步分析了这种设计取舍的实际影响。例如,如果业务数据大小分布不均,就可能加剧这种不均衡,导致热点数据被意外踢出。对于运维和开发来说,理解这一点,有助于通过调整 slab增长因子(-f 参数)或监控各 slab class 的使用率,来优化缓存策略,避免不必要的性能损耗。