51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

设计一个支持百万级用户同时请求的游戏内开屏广告系统,请从架构、技术选型、高并发处理等方面阐述你的设计方案。

9377游戏广告投放难度:困难

答案

1) 【一句话结论】
采用“CDN+负载均衡+分布式缓存+异步消息队列+分库分表数据库”的分层架构,通过缓存预热、异步解耦、分库分表扩容、重试与死信队列保障,确保百万级并发下的低延迟、高可用及数据一致性。

2) 【原理/概念讲解】
老师口吻解释关键概念:

  • CDN(内容分发网络):类比“网络快递中转站”,将广告资源缓存到离用户最近的节点(如阿里云CDN),减少网络传输延迟,降低源站压力。
  • 负载均衡(Nginx):作为请求分发器,将用户请求分发到多个广告服务实例,避免单点故障。支持轮询(静态资源,如广告图片)和最少连接(动态请求,如实时广告数据拉取),根据业务场景选择算法。
  • 分布式缓存(Redis):本地“小仓库”,存储热点广告数据(如用户ID+广告类型+广告ID)。优先从缓存读取,减少数据库访问。支持内存+持久化(RDB/AOF),确保数据可靠性。
  • 消息队列(Kafka):任务“调度中心”,解耦“请求广告”与“拉取广告”流程。高吞吐、持久化,支持重试机制,确保广告数据最终能拉取成功。
  • 分布式数据库(MySQL分库分表):存储广告素材(图片/视频)与元数据(广告ID、类型、状态)。分库策略:按广告ID范围分库(如每库存储1万-10万广告ID,避免单库压力过大);分表策略:按时间分表(如按广告上线时间,每日新增一张表,旧表归档),扩容时新增分库/分表,支持高并发读写。

3) 【对比与适用场景】

  • 分库分表策略:
    策略分库方式分表方式适用场景注意点
    按广告ID范围分库每库存储固定范围广告ID(如库1存ad_1-ad_10000,库2存ad_10001-ad_20000)按时间分表(如表名ad_20240501, ad_20240502)广告ID规模大,需水平扩展需维护分片路由表,扩容时需迁移数据
    按广告类型分库每库存储特定类型广告(如游戏内广告、游戏外广告)按时间分表广告类型多,需按类型隔离类型变化时需调整分库
  • 缓存预热机制:
    触发方式实现方式数据量适用场景
    定时任务每日凌晨0点启动,拉取当日热门广告数据(如过去7天点击量TOP10广告)1000条左右热门广告需提前加载
    用户行为触发用户登录时,拉取其历史点击广告(如过去30天点击过的广告)50条左右个性化广告预热
  • 异步任务重试与死信队列:
    机制实现方式处理逻辑
    重试机制消息消费失败后,重试3次(间隔1秒、5秒、10秒)避免瞬时故障导致数据丢失
    死信队列重试失败后,消息进入死信队列(DLQ)人工处理或批量清理

4) 【示例】
伪代码展示典型请求流程:

用户打开游戏 → 客户端发送开屏广告请求 → Nginx负载均衡分发到服务实例A  
服务A检查Redis(key=用户ID+广告类型,如"u1234-ad1")→ 若存在 → 直接返回缓存数据(广告图片/信息)  
若不存在 → 向Kafka发送“拉取广告”任务(包含用户ID、广告类型、请求时间戳)  
后台服务B(广告数据拉取服务)消费Kafka消息 → 从分布式MySQL(分库分表)拉取广告数据(如广告ID、图片URL、描述) → 存入Redis(key=用户ID+广告类型,value=广告数据) → 返回给服务A  
服务A将广告数据返回Nginx → Nginx返回给客户端(用户设备)  
(注:分库分表时,服务B根据广告ID范围选择对应库,按时间分表选择对应表;缓存预热任务每日凌晨0点启动,拉取当日热门广告存入Redis;异步任务失败后重试3次,失败后进入死信队列)

5) 【面试口播版答案】
“各位面试官好,针对百万级用户同时请求的开屏广告系统设计,我的核心思路是构建‘分层解耦、缓存优先、异步处理、分库分表扩容’的架构,确保高并发下的低延迟与高可用。首先,前端通过CDN分发请求,减少网络延迟;中间层用Nginx负载均衡分发到多个广告服务实例,避免单点故障;核心是缓存策略,优先从Redis获取广告数据,减少数据库压力;对于非缓存数据,通过Kafka异步拉取广告,避免阻塞主流程。技术选型上,负载均衡选Nginx(高性能轮询算法,适合静态资源),缓存选Redis(内存+持久化,支持热点数据),消息队列选Kafka(高吞吐、持久化),数据库用分布式MySQL(按广告ID范围分库,按时间分表,扩展容量)。高并发处理方面,通过缓存减少数据库访问,异步任务解耦请求和广告拉取,负载均衡保证请求分发均匀,CDN就近分发提升响应速度。同时,考虑缓存预热(每日凌晨拉取热门广告存入Redis),异步任务重试与死信队列保障数据可靠性,分库分表支持百万级广告数据存储。整体来看,这个方案能支撑百万级并发,同时保证广告加载的实时性和稳定性。”

6) 【追问清单】

  • 问题:如何处理缓存击穿/雪崩问题?
    回答要点:缓存击穿用互斥锁+默认值(如设置默认广告,避免全量请求数据库);缓存雪崩用随机过期时间(避免同一时间大量缓存过期,导致请求集中到数据库)。
  • 问题:消息队列的可靠性如何保障?
    回答要点:消息持久化(Kafka将消息写入磁盘),重试机制(失败后重试,最多3次),死信队列(重试失败后放入死信队列,人工处理)。
  • 问题:广告素材的版本控制怎么处理?
    回答要点:广告ID带版本号(如广告ID=ad_123_v2),更新时更新版本号,客户端按版本号请求,避免旧版本广告显示。
  • 问题:分库分表的分片键设计依据是什么?
    回答要点:按广告ID范围分库(每库存储固定范围广告ID,避免单库压力过大),按时间分表(每日新增表,旧表归档,支持历史数据查询)。

7) 【常见坑/雷区】

  • 忽略分库分表的分片键设计(如未按广告ID范围分库,导致单库压力过大),导致数据库性能瓶颈。
  • 缓存预热机制未明确触发条件(如未设置定时任务或用户行为触发),导致热门广告未提前加载,影响用户体验。
  • 异步任务无重试与死信队列机制(如消息消费失败后直接丢弃),导致广告数据拉取失败,广告无法显示。
  • 广告素材版本控制不当(如未带版本号),导致旧版本广告无法更新,用户看到过时广告内容。
  • 负载均衡算法选择不当(如固定权重),导致某些服务器过载(如轮询算法下,新实例权重低,请求少,资源未充分利用)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1