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

设计一个支持百万级用户同时参与的活动系统(如腾讯的节日红包),请说明系统架构、核心组件及如何保证高可用和低延迟。

Tencent技术运营难度:困难

答案

1) 【一句话结论】
采用微服务解耦架构,结合分布式ID(Snowflake)、低延迟消息队列(Kafka)、缓存预热+雪崩防护的Redis、分库分表数据库及动态扩容(如K8s HPA),在合理配置下支撑百万级用户同时参与,实现高可用与低延迟(假设系统单实例QPS 2万,缓存预热覆盖80%热门红包,动态扩容阈值QPS>10万)。

2) 【原理/概念讲解】
老师口吻解释核心组件逻辑:

  • 分布式ID生成器(Snowflake):通过时间戳(毫秒级)、机器ID(区分不同服务器)、序列号(同一机器内递增)组合生成全局唯一ID,类比红包的“唯一序列号”,确保高并发下无冲突且可追溯(比如每个红包ID唯一,便于后续查询和统计)。
  • 低延迟消息队列(如Kafka):通过调整Broker参数(如减少副本数至1,降低存储和延迟;增大批处理大小至16KB,减少网络开销),支持优先级队列(紧急消息优先处理,如用户拉取后立即发送通知),实现异步解耦(用户拉取红包后,消息进入队列,后台任务异步处理,避免用户等待)。
  • 缓存(Redis):活动前1小时,定时任务加载前1000个热门红包数据(按金额或参与人数排序)到缓存,设置随机TTL(5-10秒),避免缓存雪崩(随机过期时间可分散请求压力);用户拉取时优先查缓存,命中则直接返回,减少数据库压力(假设缓存命中率95%以上)。
  • 数据库分库分表:红包表按ID范围分库(每个库存储ID区间,如库1存储ID 1-1000万),用户表按用户ID分库(每个库存储部分用户ID),水平扩展处理海量数据(比如红包表单表数据量超过千万时,分库分表后每个库存储百万级数据,查询性能提升)。
  • 动态扩容:根据QPS(如超过10万次/秒)或CPU利用率(超过80%)触发,通过K8s HPA自动增加实例(每个实例配置2核4G,处理QPS约2万),扩容延迟控制在30秒内(通过预置实例池实现),确保流量突发时能快速响应。

3) 【对比与适用场景】
以“消息队列(Kafka) vs 数据库(MySQL)”为例:

对比项消息队列(Kafka)数据库(MySQL)
定义分布式消息系统,用于异步通信、解耦业务,支持高吞吐、持久化关系型数据库,存储结构化数据,支持ACID事务
特性高吞吐(百万级消息/秒)、持久化、可扩展,支持消费重试;通过调整参数(如副本数、批处理大小)优化延迟事务支持(ACID),数据一致性高,但并发下锁竞争严重,单表数据量过大时性能下降
使用场景业务解耦(如用户拉取红包后,消息进入队列,后台异步发送通知);异步任务(如统计红包数据)存储核心数据(如红包状态、用户余额,需强一致性);用户拉取红包时的状态查询(缓存未命中时)
注意点需考虑消息积压(如流量突发时,需增加消费者数量);需配置消费者数量与生产者速率匹配并发下锁竞争导致性能瓶颈(如乐观锁或悲观锁);分库分表复杂,需设计合理的分片策略

4) 【示例】
用户拉取红包的伪代码流程:

用户请求拉取红包:GET /activity/redpack/pull?userId=123&count=1
1. 服务端处理:
   a. 检查用户是否已参与(缓存/数据库,缓存优先)
   b. 从Redis缓存获取用户剩余次数(key: userId:pullCount)
   c. 若缓存命中且次数>0:
      i. 调用Snowflake生成红包ID(如id=123456789)
      ii. 更新缓存:扣减次数(Redis `decr` key: userId:pullCount)
      iii. 插入数据库:记录红包信息(`insert into redpack_table (id, userId, amount, status) values (123456789, 123, 10, 'sent')`)
      iv. 发送消息到Kafka:`topic=redpack_pull, key=userId, value=红包信息(id, amount, status)`
      v. 返回成功:`{code:200, data:{redpackId:123456789, amount:10}}`
   d. 否则:返回错误(已拉取完)
2. Kafka消费者(后台任务,每5秒轮询消费):
   a. 消费消息:`topic=redpack_pull`
   b. 调用第三方短信/短信服务发送通知
   c. 更新数据库:标记红包为“已通知”(`update redpack_table set status='notified' where id=123456789`)

5) 【面试口播版答案】
(约90秒)
面试官您好,设计百万级用户参与的活动系统,核心是构建高并发、低延迟的分布式架构。系统采用微服务解耦,关键组件包括分布式ID(Snowflake保证唯一性)、低延迟消息队列(Kafka异步解耦)、预热+雪崩防护的Redis缓存、分库分表数据库及动态扩容。高可用通过负载均衡(Nginx分发请求)、缓存+数据库读写分离、消息队列持久化实现;低延迟通过活动前预热热门红包到缓存(设置随机过期时间5-10秒)、分阶段拉取(用户先拉取部分红包,后续消息通知获取剩余)实现。具体流程:用户拉取时,先查缓存,命中则直接返回;未命中则查数据库,结果存入缓存。拉取成功后,消息进入Kafka队列,后台任务异步发送通知,避免用户等待,支撑百万级并发。比如,活动前1小时,系统会加载前1000个热门红包到Redis,用户拉取时优先从缓存获取,减少数据库压力,同时通过K8s HPA根据QPS自动扩容,应对流量突发。

6) 【追问清单】

  • 问:如何处理用户拉取红包时的超时或重试?
    答:设置请求超时(3秒),失败后重试(但需记录拉取时间戳,通过Redis存储拉取时间,避免重复拉取,比如key: userId:pullTime,过期时间5分钟)。
  • 问:如何保证红包数据的一致性?
    答:数据库事务+消息队列确认机制,拉取成功后发送Kafka消息,消费成功才标记数据库状态(如状态从“sent”更新为“notified”),避免数据不一致。
  • 问:系统如何应对流量突发(如活动开始瞬间暴增)?
    答:活动前预热缓存,增加服务器实例(K8s HPA根据QPS>10万自动扩容),增加Kafka消费者数量处理积压,确保消息队列积压数不超过1000条。
  • 问:如何监控系统性能?
    答:用Prometheus+Grafana监控请求延迟(目标<500ms)、错误率(<1%)、缓存命中率(>95%)、数据库QPS(目标<5万)、Kafka积压数(目标<1000),及时调整资源。

7) 【常见坑/雷区】

  • 未考虑分阶段拉取,导致单次请求压力过大,数据库/缓存雪崩(应设计用户分阶段拉取,比如每次拉取1个,后续通过消息通知获取剩余)。
  • 缓存未设置过期或热点数据未预热,导致缓存穿透/雪崩(需活动前预热,设置随机TTL)。
  • 分布式ID生成器单点,高并发下ID冲突或超时(需集群部署,如ZooKeeper协调,或使用阿里云UIN生成器)。
  • 消息队列积压,未设置消费者数量,影响后续处理(需动态扩容消费者,如Kafka的消费者组管理)。
  • 数据库未分库分表,单表数据量过大,性能下降(需按ID范围分库,按用户ID分库,避免单表数据量超过千万)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1