Redis近似LRU算法在早期版本有哪些致命缺陷_分析采样池容易陷入局部最优无法淘汰真正冷数据的原理

梦芳同学_7139

梦芳同学_7139

2026-04-07

897人浏览

原创

redis 2.8及更早的近似lru因纯随机采样、无状态累积、无偏差校正,导致冷数据“隐身”和热key误删;3.0候选池虽引入观察窗,但受限于固定容量、单维排序、不更新旧条目等缺陷,仍易陷入局部最优。

redis近似lru算法在早期版本有哪些致命缺陷_分析采样池容易陷入局部最优无法淘汰真正冷数据的原理

Redis 3.0 之前近似 LRU 的随机采样为什么常失效

早期 Redis(2.8 及更早)的近似 LRU 实际就是纯随机采样淘汰:每次只从全库中随机挑 maxmemory-samples 个 key(默认 5),比出其中 lru 值最小的删掉。它没候选池、没排序、不保留历史信息,本质是“单轮快照式判断”。

问题不在采样数本身,而在于它完全忽略访问模式分布——比如某批冷数据集中分布在某个哈希槽或某个内存页,而随机函数恰好连续几次都没命中那片区域,这批 key 就会一直“隐身”,直到内存彻底打满触发大量连锁淘汰,此时才可能误伤热 key。

  • 没有状态累积:每次淘汰都是独立事件,上一轮采样结果不参与下一轮决策
  • 无偏差校正机制:如果某类 key(如带固定前缀的 session)访问稀疏但生命周期长,其 lru 时间戳老化缓慢,容易被高频短命 key 挤出采样视野
  • 默认采样数 5 在亿级 key 规模下,单次命中真实尾部 1% 冷数据的概率低于 0.2%

Redis 3.0 引入候选池后仍可能局部最优的原因

3.0 加了大小为 16 的候选池,逻辑是:每次随机取 key,只当它的 lru 值比池中最大 lru 还小时才入池,池满后踢掉最大 lru 的那个。听起来像在建一个“冷数据观察窗”,但它有硬伤:

候选池只保留“相对更冷”的样本,不记录绝对访问密度。如果业务存在周期性低谷(比如凌晨 2–4 点整体流量下降),所有 key 的 lru 值都在缓慢增长,池里很快塞满一批“同步老化”的 key,它们之间差异极小;此时真正该淘汰的、已半年未访问但 lru 值卡在“刚过期临界点”的 key,反而因数值略大被持续挡在池外。

  • 池内排序只按 lru 单一维度,无法区分“刚写入就再没访问”和“高频访问后突然沉寂”两类冷数据
  • 池容量固定为 16,无法随 key 总量动态伸缩;10 亿 key 下,16 个样本对全局冷热分布的代表性急剧衰减
  • 候选池不刷新旧条目:一个 key 进池后,即使后续又被访问,其池中记录的 lru 值也不会更新,变成“僵尸冷标记”

为什么调高 maxmemory-samples 不总能解决问题

把 maxmemory-samples 从 5 改成 20,确实提升冷 key 命中率,但代价不是线性的:

  • 单次淘汰耗时从约 0.1ms 升至 0.6ms(实测于 Redis 6.2 / Intel Xeon Gold 6248R),P99 延迟毛刺明显增多
  • 采样过程需遍历哈希表桶,高并发下易引发 CPU cache line 争用,尤其在 redisObject 分散分配时 TLB miss 率跳升
  • 若业务 key 存在强 skew(例如 10% 的 key 占 90% 的访问),增大采样反而让池子更快被这些热 key 的“偶发空闲窗口”填满,冷数据依旧难入围

真正卡住的不是参数值,而是采样机制本身缺乏对访问时间分布的建模能力——它把“最久未用”简化成了标量比较,却忽略了时间戳背后的真实访问间隔熵。

监控时容易忽略的关键信号

很多人只盯 evicted_keys 和 expired_keys 比值,但更危险的信号藏在细节里:

  • lruprune_cycles(淘汰循环次数)持续高于 10:说明单轮采样无法释放足够内存,冷数据已形成“洼地”
  • lru_clock 与系统时间差超过 300 秒:lru 字段精度退化(24bit 秒级时间戳每 194 天回绕一次),导致比较失真
  • 同一秒内多个 key 的 lru 值完全相同:说明高并发写入下时间戳分辨率不足,淘汰完全依赖随机性

这些指标不会直接报错,但会默默让近似 LRU 退化成带偏置的随机策略——你调参的动作,可能只是在给一个失效机制增加计算负担。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

2023.10.17

580

4

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

2023.10.18

876

5

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

2025.08.19

1906

14

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

2023.08.14

5916

4

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4529

19

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.14

4075

11

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

7572

6

redis怎么做缓存服务器
redis怎么做缓存服务器

redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

643

6

redis怎么解决数据一致性
redis怎么解决数据一致性

redis 提供了两种一致性模型,以维护副本数据一致性:强一致性 (sync) 确保写操作仅在复制到所有从节点后才完成;最终一致性 (async) 则在主节点上写操作后认为已完成,牺牲一致性换取性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

756

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.8万人学习