游乐游手机版
首页/AI热点日报/热点详情

金华本地餐饮发票开具流程指南

类型:热点整理2026-07-25
缓存穿透需参数校验、缓存空值及布隆过滤器;击穿用互斥锁或逻辑过期结合异步刷新;雪崩通过随机TTL、预热、本地缓存和限流应对。项目实践比背名词更重要,需结合具体场景设计。

最近看 Java 后端秋招提前批的面经,Redis 被频繁问到。不是那种「Redis 有哪些数据结构」的泛泛问题,而是直接结合项目切入:你简历写了缓存优化,那么缓存穿透、击穿、雪崩分别怎么处理?为什么这么处理?线上真的实践过吗?

这题看似是八股文,但实际上很容易被追问细节。很多人一上来就背诵「穿透用布隆过滤器,击穿用互斥锁,雪崩加随机过期时间」,面试官再追问两句就卡住了。更建议按照「一次请求的完整流程」来回答。

先把三个概念彻底分清:
缓存穿透,指的是请求的数据在数据库中根本不存在。例如,有人一直查询 id 为负数的商品,缓存中没有,数据库里也没有。每次请求都直接打到数据库,这才叫穿透。
缓存击穿,指的是一个热点 key 突然过期失效。比如首页推荐配置、爆款商品库存、秒杀活动信息,平时都被缓存承载,某一刻 key 过期,大量请求同时涌向数据库。
缓存雪崩,则是一批 key 在同一时间集体失效,或者 Redis 集群本身短时间不可用。它不是单个热点 key 的问题,而是缓存层大面积失效。

面试中先把这个区别讲清楚,后面才有深入讨论的空间。否则你把击穿也说成穿透,面试官几乎会默认你只是背过题目。

穿透:不要只提布隆过滤器

穿透的第一层处理其实是参数校验。如果业务上商品 id 必须是正整数,那么负数、超长字符串、明显不合法的枚举值,应在入口处直接拦截。不要让这类请求进入缓存层,更不要让它到达数据库。

第二层才是缓存空值。当数据库查询不到结果时,可以将空结果也写入缓存,过期时间设置短一些,比如几十秒到几分钟。这样同一个不存在的 key 就不会反复查询数据库。

布隆过滤器更适合更重的场景:数据集合比较稳定、非法 key 很多、数据库压力已经明显上升。它的特点是可能误判「存在」,但不会把真实存在的数据判断为不存在。因此用它做前置过滤是可行的,但不能把它当作最终依据。

一个比较稳妥的回答可以这样组织:

  • 首先进行入参校验,拦截明显非法的请求;
  • 查询数据库为空时缓存空值,避免同一个不存在的 key 重复穿透数据库;
  • 如果非法 key 规模很大,再将合法 id 集合放入布隆过滤器做前置过滤判断。

如果面试官进一步追问「缓存空值是否会污染 Redis」,你可以回答:空值 TTL 要短、value 要小,并且可以只针对高频不存在的 key 进行缓存,而非所有 miss 都盲目写入。

击穿:互斥锁不止是写一个 SETNX

热点 key 过期时,最怕的是大量线程同时查询数据库并回写缓存。常见做法是加互斥锁:只有抢到锁的线程去查询数据库并重建缓存,其他线程等待后重试,或者直接返回旧值。

这里有个陷阱,不要提「SETNX 后再 EXPIRE」。这两个命令分开不是原子操作,中间进程崩溃可能留下死锁。Redis 里更常见的做法是用一条 SET 命令带 NX 和 EX 参数,将「只在不存在时设置」和「过期时间」合并到同一个原子命令中。解锁时还要校验 value,通常使用 Lua 脚本确保只删除自己的锁。

如果业务允许短暂接受旧数据,逻辑过期方案会更优雅:缓存中不只存放数据,还附带一个逻辑过期时间。请求到达时发现逻辑过期,不是立刻让所有线程查询数据库,而是由一个线程异步刷新,其他请求先返回旧数据。这在首页配置、排行榜、推荐位上很常见。用户看到几十秒前的数据问题不大,但数据库被击垮就是真正的事故。

一个稳妥的答法:

  • 强一致性要求高的热点 key,使用互斥锁重建缓存;
  • 读多写少、允许短暂旧值的热点 key,使用逻辑过期加异步刷新;
  • 锁必须设置过期时间,value 要唯一,删除锁时要校验 owner。

这几句话比单纯背诵「互斥锁」更有分量。

雪崩:随机 TTL 只是最低配置

雪崩的典型原因有两个。一个是大量 key 同时过期。例如批量导入缓存时,全部设置成 30 分钟,半小时后一起失效。这种情况用随机 TTL 即可缓解:在基础过期时间上加上一段随机抖动,让 key 分散失效。

另一个是缓存服务本身不可用。这就不是随机 TTL 能解决的了。需要看系统是否具备本地缓存、限流、降级、熔断机制,以及核心数据能否提前预热。

面试时可以按层次阐述:

  • 过期时间层:TTL 加随机值,避免同批 key 同时失效。
  • 热点数据层:上线或活动开始前进行预热,不等用户请求触发重建。
  • 系统保护层:本地缓存兜底、接口限流、数据库保护、非核心功能降级。

如果你项目只是普通后台系统,没有高并发活动,不要硬编秒杀场景。可以说「我没做过秒杀,但在后台字典、配置缓存中会使用随机 TTL,避免定时任务批量刷新导致同时过期」。这样的回答反而更真实可信。

面试官真正想听的,不是术语

这道题最后通常会落到你的项目经验。如果你的简历中写了 Redis,就提前想清楚这几个问题:

  • 哪些数据使用了缓存?为什么这些数据适合缓存?
  • key 如何设计?是否有前缀、版本号、业务 id?
  • TTL 设置多久?是固定值还是带随机?
  • 数据更新时,是删除缓存、更新缓存,还是延迟双删?
  • 如果缓存未命中,数据库能否扛住?是否有限流?

这比背诵十页 Redis 面试题更重要。准备这类题目时,可以把简历中的项目描述丢进面灵 AI,让它按面试官口吻连续追问五轮。第一轮通常还能回答,第三轮开始就能看出哪些地方是自己没想明白的。

来源:https://segmentfault.com/a/1190000048073409

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。