
1) 【一句话结论】采用“本地缓存+分布式缓存(如Redis)”的多级缓存架构,结合热点数据预加载,针对缓存击穿使用布隆过滤器+互斥锁优化锁竞争,针对缓存雪崩采用随机过期时间+熔断降级策略,通过异步更新或写时更新保障数据一致性,以平衡响应速度与系统稳定性。
2) 【原理/概念讲解】
ConcurrentHashMap)用于高频访问(响应更快,如学生常用知识点查询),分布式缓存(如Redis)用于共享数据(如课程答案库),类比手机App的“本地首页缓存”(即时加载)和“服务器用户数据缓存”(同步更新),本地缓存解决即时访问,分布式缓存解决数据同步。SETNX命令,若设置成功则返回1表示获取锁,否则等待);若不存在则调用AI模型生成结果,存入缓存。EX + random.randint(-5,5)实现),避免同时失效;或引入熔断器(如Hystrix),当缓存请求失败率超过阈值时,直接返回默认值或降级;同时用限流(如令牌桶)控制请求频率。3) 【对比与适用场景】
| 策略/问题 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 多级缓存 | 本地+分布式缓存 | 本地快,分布式共享 | 高频访问数据(如学生常用知识点) | 需考虑数据一致性与更新策略 |
| 缓存击穿 | 热点key失效,大量请求后端 | 瞬时流量激增 | 热点数据(如热门课程答案) | 需加布隆过滤器+互斥锁避免重复计算 |
| 缓存雪崩 | 大量key同时失效 | 系统瞬间过载 | 定时任务清理缓存 | 需随机过期+熔断降级+限流 |
4) 【示例】(伪代码):
# 请求处理流程
def get_answer(question):
# 1. 检查本地缓存
if answer in local_cache:
return local_cache[answer]
# 2. 检查分布式缓存(Redis)
if answer in redis_cache:
local_cache[answer] = redis_cache[answer]
return redis_cache[answer]
# 3. 缓存击穿处理(布隆过滤器+锁)
if not bloom_filter.contains(question):
# 获取锁
if redis.setnx(f"lock:{question}", "locked", ex=10):
try:
answer = model_api.generate(question)
redis.set(question, answer, ex=60) # 设置缓存
local_cache[question] = answer
return answer
finally:
redis.delete(f"lock:{question}") # 释放锁
else:
time.sleep(1) # 等待后重试
return get_answer(question)
# 4. 调用AI模型
answer = model_api.generate(question)
redis.set(question, answer, ex=60)
local_cache[question] = answer
return answer
# 缓存雪崩处理(随机过期)
def set_cache(key, value, ttl):
redis.set(key, value, ex=ttl + random.randint(-5, 5)) # 随机偏移
# 数据一致性(异步更新)
def update_answer(key, new_answer):
# 先更新分布式缓存
redis.set(key, new_answer, ex=60)
# 通过Kafka发送更新消息
kafka_producer.send("answer_update", key=key, value=new_answer)
5) 【面试口播版答案】
“面试官您好,针对AI助教快速响应的需求,我设计了一个多级缓存策略。首先,采用本地缓存(如ConcurrentHashMap)和分布式缓存(如Redis)结合,本地缓存处理高频访问,分布式缓存保证数据共享,这样能大幅降低响应时间。对于缓存击穿问题,针对热点key(比如热门课程的常见问题),先用布隆过滤器提前判断key是否存在,减少锁竞争;若存在则加互斥锁(如Redis的SETNX),避免大量请求同时计算;对于缓存雪崩,对缓存key设置随机过期时间(比如10-20秒),同时引入熔断器,当缓存请求失败率超过阈值时,直接返回默认值或降级。数据更新时采用异步更新(通过消息队列如Kafka),确保缓存与后端数据同步。这样既能保证响应速度,又能避免系统过载。”
6) 【追问清单】
7) 【常见坑/雷区】