Redis 在后端面试里出现频率很高,但很多候选人的回答停留在“缓存穿透用布隆过滤器、缓存击穿用互斥锁、缓存雪崩加随机过期时间”。这些答案本身不算错,但如果只停在这里,面试官很难判断你有没有真的在项目里处理过缓存问题。
真实面试里的 Redis 追问通常会从项目开始。面试官不会满足于听定义,他会继续问:你为什么在这个接口加缓存?缓存键(key,也就是缓存里的唯一标识)怎么设计?数据不一致能不能接受?热点缓存键怎么发现?如果 Redis 挂了,接口是降级还是直接失败?
先把缓存放回业务场景
回答缓存题之前,最好先说明场景。缓存不是一个独立知识点,它服务于某个读链路、某类热点数据或某个高并发场景。
比如可以这样开头:在商品详情、活动配置、用户权限、推荐结果这类读多写少的场景里,缓存主要解决数据库读压力和接口延迟问题。但我不会把所有数据都无脑放进 Redis,而是先判断数据更新频率、一致性要求、访问热点和回源成本。
这个开场比直接背概念更像真实项目,因为你先讲了选择缓存的前提。
缓存穿透不要只说布隆过滤器
面试里问缓存穿透,常见低分回答是“查询不存在的数据,解决方法是布隆过滤器”。更好的回答要补充三件事。
第一,穿透为什么危险:请求绕过缓存直接打到数据库,如果是恶意请求或参数空间很大,数据库会被大量无效查询消耗。
第二,方案不是只有一个:参数校验可以拦掉明显非法请求;空值缓存适合不存在但查询频率不高的数据;布隆过滤器适合数据量大且需要提前判断存在性的场景;接口限流用于兜住异常流量。
第三,要讲误判和更新:布隆过滤器有误判率,不能直接替代数据库;数据新增时要同步更新过滤器,删除时还要考虑重建或计数布隆过滤器。
缓存击穿要讲并发控制和旧值策略
缓存击穿是热点缓存键过期后,大量请求同时回源数据库。很多人只回答“加锁”,但面试官往往会继续追:锁粒度多大?拿不到锁怎么办?锁超时怎么办?用户能不能读旧值?
如果业务允许短时间旧值,可以讲逻辑过期:缓存里保存数据和逻辑过期时间,用户请求先返回旧值,后台线程异步刷新。它的优点是接口延迟稳定,缺点是会牺牲短时间一致性。
如果业务不能接受旧值,可以讲互斥锁:只有一个请求回源,其他请求等待或短暂重试。这里要补充锁超时、失败降级和监控指标,否则方案会显得过于理想化。
缓存一致性要先问业务能接受什么
缓存一致性不是简单回答“先更新数据库再删缓存”。面试里更专业的回答,应该先说明业务容忍度。
价格、库存、支付状态通常不能长期不一致;文章阅读数、推荐理由、配置展示可能允许短时间延迟。不同业务约束决定不同方案。
常见回答可以这样组织:普通读多写少数据,使用旁路缓存策略,也就是先读缓存,没命中再查数据库,更新时先改数据库再删缓存,并通过重试或消息补偿处理删除失败;强一致要求更高的场景,把一致性校验放到最终写链路,比如下单时重新查库存;对于热点展示数据,可以接受短暂旧值,但必须配监控和主动刷新。
热点缓存键是怎么发现的
很多候选人讲热点缓存键,只会说“预热”。但面试官经常会问:你怎么知道它是热点?
可以从几个信号讲:Redis 命令统计、网关或应用层访问日志、接口 99 分位响应时间异常、单个业务对象请求量突增、缓存命中率下降、数据库某类查询突然升高。如果项目里没有现成工具,也可以说通过日志采样和监控面板定位。
发现之后,方案包括提前预热、逻辑过期、本地缓存、热点隔离、限流降级。关键是不要把预热当成万能答案,预热解决的是可预测热点,不一定解决突发热点。
一个更完整的回答模板
如果面试官问“缓存击穿怎么解决”,可以这样回答:
先定义场景:热点缓存键过期后,大量并发请求同时回源数据库,导致数据库每秒请求数和接口延迟一起升高。
再讲判断方式:我会先看缓存命中率是否突然下降,再看慢接口是否集中在少量业务对象上,同时观察数据库连接数、慢查询和接口 99 分位响应时间。
然后给方案:如果业务能接受短时间旧值,我倾向于逻辑过期加后台刷新;如果不能接受旧值,可以用互斥锁控制回源,并设置锁超时和失败降级;活动类热点还可以提前预热并设置分散过期时间。
最后讲验证:上线后看命中率、数据库每秒请求数、接口 99 分位响应时间、锁等待时间、降级次数,确认不是只把问题从数据库转移到了 Redis 或线程池。
面试前检查
- 这个缓存服务的是哪个接口?
- 缓存键怎么设计,过期时间怎么定?
- 数据不一致时业务能不能接受?
- Redis 异常时接口如何降级?
- 热点缓存键怎么发现,而不是事后猜测?
- 方案上线后看哪些指标?
能回答这些问题,Redis 就不再是一组八股定义,而是你项目稳定性能力的一部分。
缓存方案的业务选择
Redis 缓存题最容易背成三板斧,但真实系统里每个缓存都应该先问业务能接受什么:能不能旧值,能不能丢,能不能慢,能不能回源。
| 业务问题 | 适合策略 | 不适合策略 | 原因 |
|---|---|---|---|
| 热点详情页 | 预热、逻辑过期、旧值兜底 | 每次失效都同步回源 | 回源会打垮数据库 |
| 强一致库存 | 数据库条件更新为准 | 长时间旧值兜底 | 会造成业务错误 |
| 防穿透 | 空值缓存或布隆过滤 | 所有不存在都查库 | 无效请求会放大 |
| 一致性 | 先更新数据库再删缓存 | 随意同时更新两边 | 需要考虑失败顺序 |
面试里可以说:缓存不是数据真相,数据库或权威服务才是。缓存层要讲命中率,也要讲错误时怎么保护主链路和业务正确性。