工作10年,Redis LRU和传统LRU区别,傻傻分不清?

摘要:大家好,我是小富~ 面试都背过道八股题:Redis 的内存淘汰策略 LRU 和 LFU 是什么?怎么选好? 很多同学对这两个算法的理解,只停留在都是缓存淘汰,但说不清它们具体区别,概念混淆,更不知道实际场景该怎么选? 而且 Redis 的
大家好,我是小富~ 面试都背过道八股题:Redis 的内存淘汰策略 LRU 和 LFU 是什么?怎么选好? 很多同学对这两个算法的理解,只停留在都是缓存淘汰,但说不清它们具体区别,概念混淆,更不知道实际场景该怎么选? 而且 Redis 的 key 淘汰算法其实还不是正统的 LRU 和 LFU 算法,而是基于 LRU/LFU 的一个变种。所以我们先了解下 LRU/LFU 基础算法,再看看它和变种的 Redis LRU 算法有何不同。 一、什么是 LRU 算法? LRU 的全称是 Least Recently Used(最近最少使用),核心逻辑特别好记:最近没被用过的,下次也大概率用不上。 举个例子:你电脑桌面上放着常用的软件图标(微信、IDE),这些是最近常用的;而几个月没打开过的压缩工具,会被你拖到文件夹里。这就是 LRU 的思路:保留最近使用的,淘汰最近最少使用的。 假设缓存容量只有 3,依次存入 A、B、C,此时缓存是 [A,B,C]; 若此时访问 A(A 变成最近使用),缓存顺序变为 [B,C,A] 若再存入D(缓存满了),需要淘汰最近最少使用的 B,最终缓存是 [C,A,D] LRU 的优缺点 优点: 逻辑简单:只关注使用时间,实现成本低,容易理解 响应快:插入、删除、查询的时间复杂度可以做到 O (1)(用链表 + 哈希表实现) 贴合短期局部性:很多业务场景中,最近用的数据,确实接下来更可能用(比如你刚打开的文档,接下来大概率会继续编辑)。 缺点: 突发访问误淘汰:如果突然有大量一次性数据访问,会把原本常用的缓存挤掉。 比如缓存容量 3,原本缓存 [A,B,C](A 是高频使用),突然连续访问 D、E、F,此时会淘汰 A、B、C,缓存变成 [D,E,F];但后续再访问 A 时,A 已经被淘汰,需要重新从数据库加载,导致缓存命中率骤降。 不考虑使用频率:如果 A 每天用 100 次,B 每天用 1 次,但 B 是 1 分钟前刚用,A 是 2 分钟前用,LRU 会优先淘汰 A,这显然不合理(高频使用的 A 不该被淘汰)。 实现 LRU 两种方案 方案 1:基于 LinkedHashMap Java 的LinkedHashMap自带按访问顺序排序的功能,只需重写removeEldestEntry方法,就能实现 LRU 缓存。这是最简洁的实现方式,适合业务中不需要极致性能的场景,快速开发。
阅读全文