
1) 【一句话结论】:针对教育平台热点数据,采用CDN+分布式缓存(如Redis)+本地缓存的三层架构,通过互斥锁+过期时间解决缓存击穿,随机过期时间+限流解决缓存雪崩,确保热点数据访问高效且系统稳定。
2) 【原理/概念讲解】:缓存分层是为了优化不同场景的访问性能。CDN(内容分发网络)负责缓存静态资源(如课程图片、视频片段),降低源站压力;分布式缓存(如Redis)缓存热点数据(如热门课程列表、教师信息),提升高频访问速度;应用层本地缓存(如LRU缓存)缓存最近访问的key,减少对分布式缓存的频繁查询。缓存击穿是指当缓存中某个热点key过期时,大量并发请求直接访问数据库,导致数据库压力激增;缓存雪崩是指大量key同时过期,导致缓存服务或数据库瞬间崩溃。类比:缓存击穿像水管突然爆裂,所有水流都涌向数据库;缓存雪崩像多米诺骨牌,一个key过期引发连锁反应。
3) 【对比与适用场景】:
| 问题类型 | 定义 | 特性 | 解决方案 | 适用场景 |
|---|---|---|---|---|
| 缓存击穿 | 高并发下热点key过期,所有请求直接到数据库 | 单个key过期导致瞬时高并发 | 互斥锁+过期时间(设置稍长)、热点key预热 | 热门课程ID、教师信息等高并发访问的key |
| 缓存雪崩 | 大量key同时过期,缓存服务或数据库压力激增 | 多个key集中过期 | 随机过期时间、限流降级、分布式限流 | 系统重启、定时任务触发大量key过期 |
4) 【示例】:假设热门课程ID为1,缓存key为hot_course:1,过期时间1小时。当请求访问时,首先从Redis获取缓存,若为空,尝试加分布式锁(如Redis的SETNX),锁成功后检查key是否仍为空(防止锁释放后其他线程查询),若为空则查询数据库(如MySQL),将结果存入Redis并设置过期时间为1.1小时(避免再次击穿),最后释放锁。伪代码:
def get_hot_course(course_id):
cache_key = f"hot_course:{course_id}"
# 1. 尝试从缓存获取
course = redis.get(cache_key)
if course:
return json.loads(course)
# 2. 加锁(互斥锁)
lock_key = f"lock:hot_course:{course_id}"
with redis.lock(lock_key, timeout=10): # 10秒超时
course = redis.get(cache_key)
if not course:
# 3. 查询数据库
course = db.query(f"SELECT * FROM courses WHERE id={course_id}")
# 4. 更新缓存
redis.setex(cache_key, 3600 * 1.1, json.dumps(course))
return course
5) 【面试口播版答案】:
“面试官您好,针对教育平台的热点数据,我会设计分层缓存策略并解决击穿/雪崩问题。首先,缓存分层:CDN缓存静态资源(如课程封面),分布式缓存(如Redis)缓存热门课程列表、教师信息等热点数据,应用层本地缓存(如LRU)缓存最近访问的key,提升冷启动速度。然后,缓存击穿:对于高并发访问的热点key(如热门课程ID),采用互斥锁+过期时间策略,比如设置过期时间为1.1倍正常时间,加锁后检查key是否仍为空,若为空则查询数据库,更新缓存并设置新过期时间。缓存雪崩:为每个key设置随机过期时间(如±10%),避免同时过期;同时,对缓存服务进行限流,比如通过熔断器或限流器,当请求量超过阈值时降级到数据库。这样既能保证热点数据访问速度,又能避免缓存故障导致的服务雪崩。”
6) 【追问清单】:
7) 【常见坑/雷区】: