news 2026/6/14 2:57:05

面试官:谈谈 Redis 的过期策略?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面试官:谈谈 Redis 的过期策略?

在线 Java 面试刷题(持续更新):https://www.quanxiaoha.com/java-interview

面试考察点

面试官提出这个问题,通常意在考察以下几个层面:

  1. 对缓存数据生命周期管理的理解:你是否清楚 Redis 作为缓存或数据库,需要有自动清理过期数据的能力。

  2. 对 Redis 核心机制的掌握深度:不仅仅是知道策略名称,更想知道你对其底层实现原理、协同工作方式的了解程度。

  3. 对系统资源与性能权衡的认知:如何设计过期策略才能在内存利用率、CPU 消耗、数据一致性之间取得平衡。

  4. 理论联系实际的能力:能否将策略与内存淘汰策略结合,并在实际开发中(如缓存穿透、雪崩)正确应用。

核心答案

Redis 的过期策略主要包含两个核心机制:惰性删除定期删除。它们是 Redis 用来清理过期 Key、回收内存的主要手段。此外,当这些策略无法及时释放足够内存时,会触发内存淘汰策略作为最后防线。

简单概括:

  • 惰性删除:访问 Key 时才检查并删除。

  • 定期删除:周期性抽样检查并删除。

  • 内存淘汰策略:内存不足时,按规则淘汰 Key(包括未过期的)。

深度解析

原理/机制

  1. 惰性删除 (Lazy Expiration)

  • 原理:当客户端尝试访问一个 Key 时,Redis 会先检查该 Key 是否设置了过期时间以及是否已过期。如果过期,则立即删除该 Key,并向客户端返回nil。这是一种被动、延迟的清理方式。

  • 优点:对 CPU 友好,只有在必须时才进行删除操作,不会在无关的 Key 上消耗计算资源。

  • 缺点:对内存不友好。如果一个过期 Key 永远不再被访问,它将永远占用内存,造成内存泄漏。惰性删除是保证 Redis 性能的第一道屏障。

  • 定期删除 (Periodic Expiration)

    原理:为了弥补惰性删除的缺陷,Redis 会周期性地(默认每秒 10 次,即每 100ms)主动执行一次过期 Key 清理。这个过程是自适应的:

      • 每次从设置了过期时间的 Key 字典中,随机抽取一定数量(默认 20 个)的 Key。

      • 检查并删除其中已过期的 Key。

      • 如果本轮抽查中,过期 Key 的比例超过 25%,则重复执行抽查删除过程,直到过期 Key 比例降至 25% 以下,或者本次定期删除耗时过长(防止阻塞主线程)。

    • 优点:通过限制执行时间和频率,减少了对主线程的阻塞,同时一定程度上减少了“永远不访问的过期 Key”造成的内存浪费。

    • 缺点:它仍然是一种抽样妥协的方案。难以完全精确地删除所有过期 Key,在 Key 数量巨大时,仍可能有部分过期 Key 残留。

  • 内存淘汰策略 (Eviction Policies)

    定位:这是过期策略的补充和兜底机制。当 Redis 内存使用达到maxmemory配置的阈值,且新写入数据时,如果惰性和定期删除没能及时释放空间,就会触发内存淘汰。

    8 种策略(Redis 7.x):

    • noeviction(默认):拒绝新写入,报错。适用于确需保留全部数据的场景。

    • allkeys-lru/volatile-lru:使用 LRU(最近最少使用)算法淘汰 Key。前者针对所有 Key,后者只针对设置了过期时间的 Key。

    • allkeys-lfu/volatile-lfu:使用 LFU(最不经常使用)算法淘汰 Key。LFU 比 LRU 更能精准识别热点数据。

    • allkeys-random/volatile-random:随机淘汰 Key。

    • volatile-ttl:优先淘汰过期时间更短(TTL 更小)的 Key。

    注意volatile-xxx策略只在设置了过期时间的 Key 中淘汰,但如果这部分内存不足以满足新需求,依然会触发noeviction类似的行为(报错)。生产环境常用allkeys-lruallkeys-lfu

    协同工作原理

    这两种删除策略与内存淘汰策略共同构成了 Redis 的内存管理闭环:

    // 伪代码逻辑示意 public Object get(String key) { // 1. 惰性删除:访问时检查 if (key.expired) { deleteKey(key); returnnull; } return data; } public void periodicTask() { // 2. 定期删除:后台循环任务 do { sampledKeys = randomSample(expiredKeyDict, 20); deletedCount = deleteExpiredKeys(sampledKeys); } while (deletedCount / 20.0 > 0.25 && timeLimitNotExceeded()); } public boolean writeData(String key, Object value) { // 3. 写入前检查内存,触发淘汰策略 if (usedMemory >= maxMemory) { if (!executeEvictionPolicy()) { // 执行配置的淘汰策略(如LRU) if (policy == “noeviction”) { thrownew RedisOOMError(); // 内存不足错误 } } } // ... 执行写入 }
    1. 每次读取操作都伴随一次惰性删除检查。

    2. 定期任务每秒运行多次,抽样清理,防止内存无限增长。

    3. 当内存触顶,写入操作会触发配置的淘汰策略,移除一些 Key(可能是过期的,也可能是未过期的)来腾出空间。

    最佳实践与常见误区

    • 最佳实践

    1. 根据业务形态选择淘汰策略:例如,缓存系统优先使用allkeys-lru;需要保留热点长期数据、只缓存临时数据的场景,可使用volatile-lru

    2. 合理设置过期时间:避免大量 Key 在同一时间点过期,防止定期删除压力陡增和缓存雪崩。可以添加随机偏移值,例如:expire = base_time + random(0, 300)

    3. 监控expired_keys指标:通过info stats命令查看,了解过期 Key 的清理速度是否正常。

  • 常见误区

    1. 误区一:“设置了过期时间,Key 到点就会立即被删除。” —— 错。删除依赖于惰性访问或定期扫描,存在延迟。

    2. 误区二:“volatile-lru只淘汰过期的 Key。” —— 错。它只从设置了过期时间的 Key 池子里淘汰,但淘汰的依据是 LRU 算法,被淘汰的 Key 在淘汰那一刻可能并没过期。

    3. 误区三:“内存淘汰策略可以替代过期策略。” —— 错。过期策略是主动管理生命周期,淘汰策略是内存不足时的应急措施。二者目的不同,需配合使用。

    总结

    Redis 通过惰性删除定期删除组合拳来管理 Key 过期,在 CPU 和内存效率之间取得了平衡,并以可配置的内存淘汰策略作为内存不足时的最终保障;理解这套机制对于设计高性能、高可用的缓存架构至关重要。

    👉 欢迎加入小哈的星球,你将获得:专属的项目实战(多个项目) / 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 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有4200+小伙伴加入

    1. 我的私密学习小圈子,从0到1手撸企业实战项目~ 2. SpringBoot 集成 Hera,让日志查看从 “找罪证” 变 “查答案”! 3. 面试官:什么是 Redis 大 Key 问题,如何解决? 4. 蚂蚁又开源了一个顶级 Java 项目!
    最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。 获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。
    PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。 点“在看”支持小哈呀,谢谢啦
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 13:06:20

【数据库】【MySQL】分区表深度解析:架构设计与大数据归档实践

MySQL 分区表深度解析:架构设计与大数据归档实践 MySQL 分区表通过将大表物理拆分为多个独立分区,实现了查询性能提升、数据管理灵活性和大数据归档三大核心价值。本文将详解 RANGE/LIST/HASH 分区原理、分区裁剪优化策略及 PB 级数据归档方案。一、分区…

作者头像 李华
网站建设 2026/6/10 13:17:50

1688接入API

1688 API 是阿里巴巴旗下 B2B 批发平台的官方开放接口,基于 RESTful 架构与签名认证,以 JSON 格式提供商品、订单、供应链等全链路数据,核心价值是合规高效赋能采购选品、订单履约、库存协同与分销运营,适配批发 / 零售 / 跨境 / …

作者头像 李华
网站建设 2026/6/12 5:47:03

HoRain云--掌握jQuery事件处理全攻略

🎬 HoRain 云小助手:个人主页 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。 目录 ⛳️ 推荐 …

作者头像 李华
网站建设 2026/6/11 12:04:18

基于springboot 心理咨询预约系统

心理咨询预约 目录 基于springboot vue心理咨询预约系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue心理咨询预约系统 一、前言 博主介绍&…

作者头像 李华