百度面试官:Redis 内存满了怎么办?你有想过吗?

张开发
2026/4/7 21:33:34 15 分钟阅读

分享文章

百度面试官:Redis 内存满了怎么办?你有想过吗?
在线 Java 面试刷题已更新239题图文并茂https://www.quanxiaoha.com/java-interview面试考察点基础掌握度面试官不仅仅是想知道 Redis 有过期策略更是想知道你是否清楚 Redis 采用的是惰性删除 定期删除的组合方案而不是定时删除以及为什么要这样设计。原理理解深度考察你是否了解过期字典的内部结构定期删除的采样逻辑随机抽取、循环检测以及这些设计背后的性能与内存权衡。知识关联能力能否自然过渡到 过期策略解决不了内存问题时怎么办 → 内存淘汰策略maxmemory-policy展示完整的知识体系。核心答案Redis 采用惰性删除 定期删除两种策略配合使用策略触发时机行为特点惰性删除访问 Key 时发现过期才删除对 CPU 友好但可能有垃圾数据残留定期删除每隔一段时间随机抽查一批 Key删除过期的折中方案平衡 CPU 和内存一句话结论Redis不使用定时删除到期立即删因为那会消耗大量 CPU 资源。而是用 惰性 定期 的组合策略在 CPU 和内存之间取一个平衡。如果过期策略清理不过来内存还是满了就会触发内存淘汰策略。深度解析一、三种过期策略的理论对比在讲 Redis 的方案之前先了解一下理论上过期策略有三种img上图展示了三种过期策略的理论对比定时删除每个 Key 设置一个定时器到期立即删除。内存最优但 CPU 开销太大Redis没有采用。惰性删除只在访问时检查。CPU 最友好但过期不访问的 Key 会一直占内存Redis采用。定期删除每隔一段时间抽查。是 CPU 和内存的折中方案Redis采用。Redis 选择惰性 定期的组合策略既不会消耗过多 CPU又能及时清理大部分过期数据。二、过期字典Redis 如何记录 Key 的过期时间img上图展示了 Redis 存储过期时间的内部结构Redis 在每个数据库redisDb中维护了两个字典**dict**主字典存储所有 Key-Value 数据和 **expires**过期字典存储设置了过期时间的 Key 及其过期时间戳。过期字典的 key 指向主字典中的同一个 Key 对象不是副本所以不会额外占用太多内存。当检查一个 Key 是否过期时只需在expires字典中查找对应的时间戳与当前时间比较即可。三、惰性删除的工作流程img上图展示了惰性删除的判断流程核心思路每次访问 Key 时顺便检查一下是否过期。如果过期了就删除并返回空没过期就正常返回数据。优点对 CPU 极度友好只有在业务需要访问时才执行删除操作不会浪费 CPU 资源。缺点如果有些 Key 过期了但一直没有被访问它们就会一直占用内存成为 垃圾数据。四、定期删除的工作流程定期删除是 Redis 主动清理过期数据的机制它的执行逻辑比惰性删除复杂得多。img上图展示了定期删除的完整流程核心逻辑随机抽取每 100ms 从过期字典中随机抽取 20 个 Key检查是否过期。自适应循环如果这 20 个 Key 中过期的比例超过 25%说明当前过期 Key 很多就再随机抽 20 个继续清理直到过期比例降到 25% 以下或者执行时间超过上限默认 25ms。为什么限制 25ms定期删除是在 Redis 主线程中执行的如果清理时间过长会阻塞正常请求所以必须严格限制单次执行时长。定期删除的局限性由于是随机抽样总会有一些过期 Key 被遗漏不会全扫一遍。如果过期 Key 数量非常多而随机抽取的概率有限仍然会有大量过期 Key 残留在内存中。五、过期策略 内存淘汰策略 完整方案惰性 定期 只能清理过期了的 Key。如果有些 Key 没有设置过期时间或者过期策略清理速度跟不上新 Key 的写入速度内存还是会满。这时就需要内存淘汰策略出场了。# redis.conf 配置最大内存和淘汰策略 maxmemory 4gb maxmemory-policy allkeys-lruRedis 8 种内存淘汰策略策略行为适用场景noeviction不淘汰写入直接报错默认数据不能丢失allkeys-lru从所有 Key 中淘汰最久未使用的通用缓存推荐allkeys-lfu从所有 Key 中淘汰使用频率最低的Redis 4.0热点数据明显的缓存allkeys-random从所有 Key 中随机淘汰无访问热点volatile-lru从设置了过期的 Key 中淘汰最久未使用的混合使用部分持久化volatile-lfu从设置了过期的 Key 中淘汰使用频率最低的混合使用volatile-random从设置了过期的 Key 中随机淘汰混合使用volatile-ttl从设置了过期的 Key 中淘汰剩余时间最短的业务有明确 TTL 需求生产环境推荐allkeys-lru通用缓存或allkeys-lfu热点明显的缓存。面试高频追问追问一为什么 Redis 不用定时删除定时删除需要为每个设置了过期时间的 Key 维护一个定时器如果同时有几十万个 Key 设置了过期时间就会有几十万个定时器同时运行严重消耗 CPU 资源影响 Redis 处理正常请求的性能。Redis 作为高性能缓存把 CPU 留给业务处理更重要。追问二LRU 和 LFU 淘汰策略的区别LRULeast Recently Used淘汰最久没被访问的 Key基于 最近访问的数据大概率还会被访问 的假设。Redis 的 LRU 是近似算法随机采样 N 个 Key默认 5 个淘汰其中最久未访问的。LFULeast Frequently Used淘汰访问频率最低的 Key基于 访问频率高的数据更有价值 的假设。Redis 4.0 引入更适合热点数据明显的场景比如 20% 的数据占 80% 的访问量。追问三如何查看 Redis 当前内存使用情况# 查看内存使用详情 INFO memory # 关键指标 # used_memory已用内存 # maxmemory最大内存限制 # maxmemory_policy当前淘汰策略常见面试变体变体一Redis 的 Key 过期了是怎么被删除的变体二Redis 过期策略和内存淘汰策略的区别变体三Redis 内存满了怎么办变体四Redis 的 LRU 算法了解吗是精确的还是近似的记忆口诀过期策略惰性删除访问才删 定期删除随机抽查过期超 25% 继续抽。为什么不单独用一种惰性删不干净残留垃圾定期删不精确随机抽样两者互补。内存满了过期策略搞不定 → 内存淘汰策略接手 →allkeys-lru最常用。总结Redis 过期策略采用惰性删除 定期删除的组合方案。惰性删除在访问时才检查并删除过期 Key对 CPU 友好定期删除每 100ms 随机抽样一批 Key 清理过期的防止大量过期数据残留。两者互补在 CPU 和内存之间取得平衡。如果过期策略仍无法释放足够内存就会触发内存淘汰策略推荐allkeys-lru或allkeys-lfu。加入小哈的星球你将获得:专属的项目实战多个项目 / 1v1 提问 /Java 学习路线 /学习打卡 / 每月赠书 / 社群讨论《秒杀系统设计》正在更新中..., 由单体到微服务渐进式地搭建一个支撑高并发的秒杀系统。《Spring AI 应用项目》已完结, 基于 Spring AI Spring Boot 3.x JDK 21;《从零手撸仿小红书微服务架构》 已完结基于 Spring Cloud Alibaba Spring Boot 3.x JDK 17..., 点击查看项目介绍演示地址http://116.62.199.48:7070/《从零手撸前后端分离博客项目全栈开发》2期已完结,演示链接http://116.62.199.48/;专栏阅读地址https://www.quanxiaoha.com/column截止目前累计输出 100w 字讲解图 4013 张还在持续爆肝中..后续还会上新更多项目目标是将 Java 领域典型的项目都整一波戳我加入学习解锁全部项目已有4500小伙伴加入1. 我的私密学习小圈子从0到1手撸企业实战项目~ 2. 滴滴二面你项目为什么选择 RocketMQ而不是 Kafka? 我支支吾吾.... 3. 流程引擎的架构设计 4. 得物二面Redis 如何高效安全的遍历所有 Key修订版最近面试BAT整理一份面试资料《Java面试BATJ通关手册》覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。 获取方式点“在看”关注公众号并回复 Java 领取更多内容陆续奉上。PS因公众号平台更改了推送规则如果不想错过内容记得读完点一下“在看”加个“星标”这样每次新文章推送才会第一时间出现在你的订阅列表里。 点“在看”支持小哈呀谢谢啦

更多文章