更多面试题请看这里:https://interview.raoyunsoft.com/
面试题专栏会持续更新欢迎关注订阅
一、缓存雪崩
问题本质 :大量缓存同时失效,导致请求直接穿透到数据库,引发数据库压力激增甚至宕机。
典型场景:
- 缓存集群重启
- 相同过期时间的大批量缓存集中失效
- 缓存服务不可用
解决方案:
- 错峰失效:对缓存过期时间添加随机值(如基础时间±30分钟)
- 熔断降级:通过 Hystrix 等工具实现请求限流
- 多级缓存:采用本地缓存(Caffeine)+ Redis 的多层结构
- 热点永不过期:对核心数据设置逻辑过期时间,异步更新
graph LR
A[请求] --> B{缓存是否存在?}
B -- 是 --> C[返回缓存数据]
B -- 否 --> D[数据库查询]
D --> E[更新缓存]
D --> F[返回数据]
style B fill:#f9f,stroke:#333
style D stroke:#f00,stroke-width:2px
二、缓存穿透
问题本质 :恶意查询不存在的数据,绕过缓存直击数据库。
典型特征:
- 查询 key 在数据库不存在
- 高并发非法请求(如遍历负整数 ID)
解决方案:
- 布隆过滤器 (Bloom Filter):
- 前置拦截非法 key
- 使用 Redis 4.0+ 的
BF.ADD/BF.EXISTS命令 - 特点:空间效率极高,存在误判率(可控制在 1% 内)
key存在 key不存在 命中 未命中 请求 布隆过滤器 Redis缓存 直接返回空 返回数据 查数据库
- 空值缓存 :
- 对查询为空的结果缓存短时间(如 5 分钟)
- 需设置最大空值数量防止内存溢出
布隆过滤器原理:
- 使用 k 个哈希函数计算 key 的位图位置
- 写入:所有位置置为 1
- 查询:所有位置均为 1 则可能存在(有误判),任一为 0 则必然不存在
32bit/64bit 数据排重方案:
| 数据类型 | 方案 | 空间复杂度 |
|---|---|---|
| 32bit | Bitmap | 512MB (2³² bit) |
| 64bit | 布隆过滤器+分片 | 可控误判率 |
三、缓存预热
核心思想 :系统上线前主动加载热点数据到缓存。
实施策略:
- 定时任务:通过 Quartz 在低峰期预加载
- 启动加载 :Spring Boot 的
ApplicationRunner初始化缓存 - 动态预热:基于 Nginx 日志分析实时热点 key
操作流程:
后台系统 Redis DB 1. 查询热点数据列表 2. 返回空(首次) 3. 批量查询数据 4. Pipeline 批量写入 后台系统 Redis DB
四、缓存更新
更新策略对比:
| 策略 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 定时清理 | 实现简单 | 实时性差 | 低频更新数据 |
| 请求触发更新 | 数据实时性强 | 增加请求延迟 | 高频访问核心数据 |
| 消息队列通知 | 解耦业务与缓存 | 系统复杂度高 | 分布式环境 |
最佳实践:
- 组合使用:核心数据用请求触发更新 + 普通数据定时清理
- 写操作同步:
DB 更新 → 发 MQ → 消费更新缓存
五、缓存降级
核心目标 :保障核心服务可用性,牺牲非关键功能。
降级策略:
- 返回默认值 :
- 如商品详情页库存显示"服务繁忙"
- 使用 Hystrix 的
fallback机制实现
- 开关降级 :
- 通过 Apollo 配置中心动态切换降级策略
- 分级预案:
| 故障级别 | 特征 | 应对措施 |
|---|---|---|
| 一般 | 短暂超时(<1s) | 自动重试+日志记录 |
| 警告 | 成功率波动(90%-95%) | 局部降级+邮件告警 |
| 错误 | 可用率<90% | 全局降级+短信通知 |
| 严重错误 | 数据异常/连接池耗尽 | 人工介入+熔断所有非核心服务 |
降级原则:
- 优先保证读服务:如商品列表、详情页
- 写服务谨慎降级:下单、支付必须保障一致性
- 降级状态可视化:通过 Grafana 监控面板实时展示