Redis 面试里,缓存击穿是高频题。很多候选人会说“加锁”或“逻辑过期”,但面试官往往继续问:热点怎么发现?拿不到锁的请求怎么办?可以返回旧值吗?数据库已经很慢了,还能不能继续回源?
面试官真正想听什么
缓存击穿不是定义题,而是稳定性题。一个热点缓存键过期后,如果大量请求同时发现缓存没有数据,它们会一起查询数据库。危险不在于缓存没了,而在于回源流量突然放大。
所以回答要包含四部分:怎么发现热点、怎么控制回源、旧值能不能返回、上线后看什么指标。
互斥锁和逻辑过期怎么选
如果业务不能接受旧值,比如支付状态、库存校验,互斥锁更合适:只有一个请求回源,其它请求等待、重试或失败降级。但锁要有超时,避免请求一直挂住。
如果业务可以接受短时间旧值,比如文章详情、活动配置、推荐理由,可以用逻辑过期:缓存里保留数据和逻辑过期时间,用户请求先返回旧值,后台异步刷新。它牺牲短时间一致性,换取接口稳定。
降级要提前设计
热点缓存失效时,如果数据库已经慢,继续让所有请求等待只会恶化。可以做限流、返回兜底文案、只展示基础信息、暂时关闭非核心模块。降级不是偷懒,而是明确保护核心链路。
项目回答可以这样说:我们对热点详情页做缓存时,不只设置过期时间,还监控命中率、回源耗时和数据库查询量。热点数据允许短时间旧值,因此采用逻辑过期加后台刷新;如果刷新失败,继续返回旧值并告警。对于强一致字段,不放在这个缓存里,而是在下单链路重新校验。
这比单纯说“加锁”更像真实项目经验,因为它承认不同业务字段有不同一致性要求。
如果面试官继续问“怎么知道它是热点”,可以从监控信号回答:单个缓存键访问量突然升高、缓存命中率下降、数据库同类查询增多、接口 99 分位响应时间升高。这里的 99 分位响应时间,是指 99% 的请求能完成的耗时,用来观察最慢那部分用户是否被影响。能把发现、处理和验证串起来,缓存题就不再是背概念。
热点缓存的取舍表
缓存击穿不是只有一个标准答案。能不能返回旧值、要不要等待锁、是否允许降级,取决于业务字段的性质。面试时把这些取舍讲清楚,会比背“互斥锁、逻辑过期、随机过期”更像真实项目。
| 业务特征 | 推荐策略 | 主要风险 | 需要观察什么 |
|---|---|---|---|
| 文章详情、活动配置 | 逻辑过期加后台刷新 | 短时间展示旧值 | 命中率、刷新失败次数 |
| 库存、支付状态 | 强一致查询或短锁保护 | 等待时间变长 | 锁等待、数据库压力 |
| 首页热门榜单 | 预热加分批刷新 | 榜单短暂滞后 | 热点 key 访问量 |
| 下游服务已经变慢 | 限流和兜底结果 | 信息不完整 | 降级比例和用户反馈 |
回答里最好补一句:缓存是为了保护系统,不是为了绕开业务一致性。强一致字段不要随便放进可返回旧值的缓存里,展示型字段才适合用旧值换稳定性。