
1) 【一句话结论】在360广告投放系统高并发项目中,通过分库分表(单库QPS从5万降至1万)、缓存穿透优化(布隆过滤器+空值缓存,穿透率<1%)、请求限流(令牌桶限流至5万QPS),高峰期响应时间从2秒降至0.3秒,数据库压力降低80%,系统稳定性显著提升。
2) 【原理/概念讲解】老师会解释高并发场景下的压力来源。比如,系统在广告投放高峰期(每日18-22点),QPS达到10万,数据库连接池耗尽,响应时间超过2秒。关键技术点:
3) 【对比与适用场景】用要点说明:
4) 【示例】缓存穿透解决方案伪代码(布隆过滤器+空值缓存+重试逻辑):
def get_ad_info(ad_id):
# 布隆过滤器判断是否存在
if not is_in_bloom_filter(ad_id):
return None # 直接返回,避免数据库查询
# 缓存未命中
info = redis.get(f"ad_info:{ad_id}")
if info:
return json.loads(info)
# 数据库查询
info = db.query("SELECT * FROM ads WHERE id = ?", ad_id)
if info:
redis.set(f"ad_info:{ad_id}", json.dumps(info), ex=3600)
return info
# 存空值缓存,防止后续穿透
redis.set(f"ad_id:{ad_id}", "", ex=60)
return None
# 空值缓存过期后处理(假设有监控触发重试)
def handle_cache_miss(ad_id):
if redis.get(f"ad_id:{ad_id}") == "":
# 触发重试逻辑,比如再次布隆过滤器判断或直接数据库(带降级)
info = db.query("SELECT * FROM ads WHERE id = ? FOR UPDATE", ad_id) # 降级处理
if info:
redis.set(f"ad_info:{ad_id}", json.dumps(info), ex=3600)
return info
return None
布隆过滤器实现:位数组大小为2^16,3个hash函数(如murmurhash3),误判率约1%。
5) 【面试口播版答案】“我参与的是360广告投放系统的高并发项目。当时遇到的挑战是系统在投放高峰期(比如每日广告点击高峰),QPS达到10万,数据库连接池耗尽,响应时间超过2秒。具体来说,缓存穿透问题比较突出——当查询不存在的广告ID时,所有请求都直接访问数据库,导致数据库压力激增。解决方案上,我们做了三方面优化:一是通过布隆过滤器快速判断key是否存在,避免无效数据库查询;二是对于高频查询的key,设置永不过期或预热机制;三是采用分库分表策略,将广告数据按ID哈希分片到多个数据库,单库压力降低80%以上。同时引入请求限流,通过令牌桶算法限制每秒请求量,防止系统雪崩。这些措施实施后,系统在高峰期的响应时间从原来的2秒降至0.3秒,数据库压力降低80%,系统稳定性显著提升。”
6) 【追问清单】
7) 【常见坑/雷区】