1) 【一句话结论】
双十一活动期间,直播平台因高并发下缓存穿透导致数据库压力激增,连接池耗尽,服务崩溃,核心是缓存策略不当引发雪崩效应。
2) 【原理/概念讲解】
要理解故障根因,需先明确几个关键概念:
- 缓存穿透:请求的key在缓存和数据库中都不存在(如恶意请求或未初始化的key),高并发下直接冲向数据库,导致数据库压力过大。类比:水库的洪水直接冲向下游,没有拦截设施。
- 缓存击穿:某个热点key在缓存中过期,大量请求同时访问数据库,导致数据库瞬间压力过大。类比:水库堤坝突然被冲破,洪水瞬间涌出。
- 缓存雪崩:大量key同时过期,导致缓存失效,所有请求都去数据库,引发系统崩溃。类比:多米诺骨牌效应。
- 数据库连接池:管理数据库连接的池化机制,高并发下需足够连接数,否则连接耗尽导致服务不可用。
3) 【对比与适用场景】
| 概念 | 定义 | 根因 | 影响 | 解决方法 |
|---|
| 缓存穿透 | 请求key不存在,直接查数据库 | key未在缓存,且数据库无数据 | 数据库压力激增,连接池耗尽 | 布隆过滤器拦截无效请求,缓存空值 |
| 缓存击穿 | 热点key过期,大量请求查数据库 | key在缓存过期,高并发请求 | 数据库瞬间压力过大 | 设置过期时间不统一,加互斥锁,预热 |
| 缓存雪崩 | 大量key同时过期,缓存失效 | key集中过期时间(如每天0点) | 所有请求去数据库,系统崩溃 | 设置过期时间随机,预热,限流 |
4) 【示例】
伪代码展示请求流程(含缓存穿透场景):
用户请求:/live/123
1. 检查Redis缓存(key: live:123:info)
2. 缓存未命中:
a. 检查布隆过滤器(key: live:123:bf),若存在则直接返回404
b. 查数据库(SELECT * FROM live WHERE id=123),若数据存在则存入缓存
3. 缓存命中:返回缓存数据
恶意请求:/live/invalid
1. 检查缓存:无
2. 检查布隆过滤器:无
3. 直接查数据库:无效,导致大量无效查询,数据库压力过大,连接池耗尽。
5) 【面试口播版答案】
当时双十一活动期间,直播平台突然出现崩溃,用户无法进入直播间或观看直播。首先,通过系统监控发现CPU、内存急剧飙升,数据库连接数接近上限。接着分析日志,发现大量请求直接访问数据库,判断是缓存穿透问题。排查时,用Redis监控工具看到缓存命中率极低,日志里大量“key not found”记录。解决方案:临时增加数据库连接池大小,同时通过布隆过滤器拦截无效请求;根本修复是优化缓存key,设置热点数据预热任务,并调整缓存过期时间。后续预防措施包括定期压力测试,监控缓存命中率,设置告警阈值,确保系统在高并发下稳定运行。
6) 【追问清单】
- 问:为什么用布隆过滤器来拦截无效请求?
答:布隆过滤器可高效判断key是否存在于集合中,空间占用小,适合高并发场景下快速过滤无效请求,避免直接访问数据库。
- 问:数据库连接池耗尽后,如何快速恢复服务?
答:通过增加连接池大小(临时措施),同时优化数据库查询,减少连接占用时间,并监控连接状态,及时释放闲置连接。
- 问:缓存预热的具体流程是怎样的?
答:提前将热门直播数据加载到缓存中,比如在活动前1小时启动任务,将所有直播间的数据存入Redis,确保活动开始时缓存有数据,减少数据库压力。
- 问:如果是缓存击穿,除了布隆过滤器,还有什么方法?
答:设置过期时间不统一(比如随机偏移),加互斥锁,当第一个请求获取数据时,锁住key,其他请求等待,避免重复查询数据库。
- 问:后续是否做了压力测试验证修复效果?
答:是的,在修复后进行了压力测试,模拟双十一流量,验证系统在高并发下的性能,确保缓存策略和连接池配置能支撑流量。
7) 【常见坑/雷区】
-
- 仅描述故障现象,未深入分析根因(如只说系统崩溃,没说明是缓存或数据库问题)。
-
- 排查步骤不具体,未提及使用的工具(如监控、日志分析工具),显得经验不足。
-
- 解决方案仅给出临时措施,未说明根本性修复(如只说增加连接池,没提优化缓存策略)。
-
- 预防措施过于笼统,未结合具体措施(如压力测试、监控告警),缺乏可操作性。
-
- 忘记说明高并发下的系统设计考虑(如限流、熔断),导致回答不全面。