Redis LRU算法如何实现?Redis内存淘汰的底层逻辑是什么?

陌强吖_4614

陌强吖_4614

2026-08-13

230人浏览

原创

redis的lru字段在lru模式下存储的是对象最后一次访问时间相对于全局server.lruclock的24位偏移值,非绝对时间戳;在lfu模式下则拆分为高16位ldt(分钟级时间戳)和低8位logc(初始为5的对数计数器)。

redis lru算法如何实现?redis内存淘汰的底层逻辑是什么?

Redis 的 LRU 不是标准链表实现,而是用 24 位 lru 字段 + 随机采样来近似判断“最近最少使用”,精度可控但开销极低。

Redis 的 lru 字段到底存什么?

每个 redisObject 结构体里有个 lru 成员,占 24 位,存储的是“最近一次访问时间”相对于全局 lruclock 的秒级偏移(不是绝对时间戳)。由于只有 24 位,它会每 ~194 天回绕一次,但这对淘汰逻辑无实质影响——只要相对顺序能大致反映访问新旧即可。

这个字段在每次 key 被读写时更新,不依赖额外数据结构,也不触发链表移动,所以零内存膨胀、零 O(n) 移动开销。

  • lru 值越小,代表该 key 越久没被访问(注意:不是“数值小=时间早”,而是“差值大=更久未访问”)
  • 它不记录毫秒级精度,也不做全量排序,只服务于采样比较
  • 如果你用 OBJECT IDLETIME <key></key> 查看,返回的就是当前 lruclock - lru 的秒数

为什么不用精确 LRU?采样怎么工作?

精确 LRU 需要维护全局双向链表,每次访问都要调整节点位置,对高并发写密集场景会造成显著锁竞争和 CPU 毛刺。Redis 选择用空间换时间,用概率逼近确定性。

当触发淘汰时(used_memory > maxmemory),Redis 会:

Redis Skill - 高性能缓存管理
Redis Skill - 高性能缓存管理

Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。

下载
  • 根据配置的 maxmemory-samples(默认 5)随机选出 N 个候选 key
  • 比较它们的 lru 值,挑出“最老”的那个(即 lruclock - lru 最大的)
  • 如果该 key 是 volatile-lru 策略,则还要先过滤掉没设过期时间的 key
  • 重复该过程,直到释放足够内存

增大 maxmemory-samples(比如调到 10 或 20)能提升淘汰准确率,但会增加 CPU 占用;小于 5 则容易误杀热点 key,尤其在访问模式陡峭时(比如突发流量后大量冷 key 残留)。

volatile-lru 和 allkeys-lru 的关键区别在哪?

区别不在算法本身,而在候选集范围 —— 这直接影响淘汰安全性和适用场景:

  • volatile-lru:只从已设置 EXPIRE 的 key 中采样淘汰。适合缓存层,保证永不过期的元数据、配置类 key 不被误删
  • allkeys-lru:对所有 key 无差别采样。适合纯缓存场景,且你明确接受“任何 key 都可能被淘汰”
  • 如果用了 volatile-lru,但大部分 key 没设过期时间,那么实际可用的候选集很小,可能导致频繁触发 evicted_keys 但内存降不下来,甚至退化为类似 noeviction 的行为

注意:volatile- 类策略不会主动清理未设置过期时间的 key,哪怕内存已满;而 allkeys- 类策略会无条件参与淘汰,不管有没有 EXPIRE。

LRU 在 Redis 里真正“失效”的几个典型时刻

近似算法再好,也有边界条件让它表现失真:

  • 冷启动后首次大批量写入:所有 key 的 lru 值接近,采样无法区分新旧,容易随机淘汰
  • 访问模式突变(如 AB 测试切流):旧热点突然变冷,但 lru 值还没衰减足够,仍被保护;新热点因时间短,lru 值新,反而易被淘汰
  • maxmemory-samples 过小 + key 总数极少(比如只有几十个):随机性压倒统计意义,淘汰结果接近随机
  • 大量 key 同时被访问(如定时任务批量读):它们的 lru 值被集中刷新,导致“集体年轻化”,掩盖真实热度差异

这些情况不是 bug,而是设计取舍的结果 —— 它优先保障吞吐和延迟稳定性,把精度让渡给工程可维护性。真要强一致性 LRU,得自己在客户端或 proxy 层补。

相关文章

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

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

下载

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

相关专题

更多
页面置换算法
页面置换算法

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

2023.08.14

5076

4

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

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

2023.11.02

4249

19

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

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

2023.11.14

3735

11

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

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

2024.04.02

6732

6

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

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

2024.04.07

623

6

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

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

2024.04.07

736

6

mysql和redis怎么保证双写一致性
mysql和redis怎么保证双写一致性

确保 mysql 和 redis 双写一致性的技术包括:1、事务性更新:同时更新 mysql 和 redis,保证一致性;2、主从复制:mysql 主服务器更改同步到 redis 从服务器;3、基于事件的更新:mysql 记录更改并发送到 redis等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

6282

6

redis缓存一般存些什么数据
redis缓存一般存些什么数据

redis缓存中存储的数据类型包括:字符串、哈希、列表、集合、有序集合、位图、地理空间数据和hyperloglog。这些数据类型适用于存储各种数据,从简单信息到复杂对象和地理位置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1140

6

redis的8种数据类型有哪些
redis的8种数据类型有哪些

redis 提供 8 种数据类型:字符串(文本、数字、二进制)、哈希(键值对)、列表(有序集合)、集合(无序唯一元素)、有序集合(按分数排序)、地理空间(地理位置)、hyperloglog(估计大数据基数)和位图(位序列存储)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1016

6

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习