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

设计一个支持百万级用户同时在线的直播弹幕系统,要求低延迟(毫秒级)且高可用。请从系统架构、数据流、容错机制、技术选型等方面分析,并说明如何保证弹幕的实时性和系统的可扩展性。

快手C++开发工程师 📦 工程类难度:困难

答案

1) 【一句话结论】
采用“边缘节点-消息队列-核心服务器-缓存-实时通信”分层架构,通过边缘节点降低网络延迟,消息队列异步解耦,Redis缓存加速读取,结合WebSocket实时推送,实现百万级用户毫秒级低延迟和高可用弹幕系统。

2) 【原理/概念讲解】
系统分为四层:客户端(用户设备,通过WebSocket连接边缘节点)、边缘节点(CDN/边缘服务器,靠近用户,负责接收弹幕并转发)、消息队列(如Kafka,异步分发消息)、核心服务器(处理业务逻辑,包括消息消费、缓存/数据库操作、推送)、实时通信(WebSocket,推送弹幕)。
数据流:用户发送弹幕→边缘节点接收→Kafka异步分发→核心服务器消费→Redis缓存(快速读取)+数据库持久化→WebSocket推送给其他用户。
容错机制:Kafka幂等消费(确保消息不重复)、重试机制(指数退避,避免堆积)、核心服务器集群+负载均衡(故障转移)。
缓存策略:热点数据预热(提前加载),缓存击穿(布隆过滤器过滤无效请求+互斥锁加锁缓存),缓存雪崩(随机化TTL,避免集中失效)。
边缘节点与核心服务器的网络:专线或低延迟网络(如CDN的P2P连接),减少抖动。

3) 【对比与适用场景】

组件定义特性使用场景注意点
Kafka分布式消息队列高吞吐、持久化、顺序性、多分区边缘节点到核心服务器的异步解耦分区数量影响吞吐量,需根据并发调整
RabbitMQ消息队列队列模型、可靠投递、支持多种协议小型系统或复杂路由吞吐量低于Kafka,适合低延迟场景
Redis缓存数据库低延迟、内存存储、支持数据结构弹幕实时读取(热点数据)需要缓存击穿/雪崩防护,TTL控制过期

4) 【示例】
客户端发送弹幕(JSON):

{
  "userId": "user123",
  "roomId": "live-001",
  "content": "欢迎观看!",
  "timestamp": 1672508000
}

边缘节点(CDN)收到后,推送到Kafka主题“danmu-live-001”:

kafka-producer --topic danmu-live-001 --value "user123|live-001|欢迎观看!|1672508000"

核心服务器(C++服务)消费Kafka消息:

void processDanmu(const std::string& msg) {
    // 解析消息
    auto parts = split(msg, '|');
    std::string userId = parts[0];
    std::string roomId = parts[1];
    std::string content = parts[2];
    long long ts = std::stoll(parts[3]);

    // 缓存击穿防护(布隆过滤器)
    if (!isHotDanmu(roomId, content)) {
        // 互斥锁加锁缓存
        std::lock_guard<std::mutex> lock(danmuMutex);
        if (!redisClient.exists("danmu:" + roomId + ":" + std::to_string(ts))) {
            redisClient.set("danmu:" + roomId + ":" + std::to_string(ts), content, 60); // TTL 60秒
        }
    }

    // 存入数据库(持久化)
    db.insert("danmu", {roomId, userId, content, ts});

    // WebSocket广播
    webSocketServer.broadcast(roomId, content);
}

5) 【面试口播版答案】
设计百万级直播弹幕系统,核心是分层架构:客户端通过边缘节点(CDN)接入,消息通过Kafka异步分发,核心服务器用Redis缓存并持久化,用WebSocket实时推送。低延迟靠边缘节点靠近用户,高可用靠消息重试和负载均衡。具体来说,用户发送弹幕后,边缘节点接收并推送到消息队列,核心服务器消费后存入Redis(快速读取)和数据库(持久化),再通过WebSocket推送给其他用户。消息队列保证异步处理,避免阻塞核心服务器,从而实现毫秒级延迟。同时,核心服务器集群和负载均衡器确保高可用,消息重试机制(指数退避)处理消息丢失。缓存方面,热点数据提前预热,避免缓存击穿用布隆过滤器+互斥锁,缓存雪崩用随机化TTL,消息队列分区根据并发调整,平衡吞吐量与延迟。

6) 【追问清单】

  • 问:如何配置消息队列的分区数量?
    答:根据历史消息吞吐量,比如每个分区处理1000条/秒,百万用户场景下设置1000个分区,通过调整分区数量平衡延迟(分区越多,延迟越高,但吞吐量越大)。
  • 问:缓存击穿如何处理?
    答:使用布隆过滤器过滤无效请求,避免热点数据导致数据库压力;同时用互斥锁加锁缓存,确保缓存写入的原子性。
  • 问:系统如何扩展?
    答:边缘节点按区域部署(如每个城市一个节点),核心服务器水平扩展(增加实例),消息队列增加分区,Redis集群,WebSocket服务器集群,实现按需扩展。

7) 【常见坑/雷区】

  • 坑1:忽略边缘节点的作用,直接让用户请求到核心服务器,导致网络延迟高(如用户在海外,延迟超过100ms,不符合毫秒级要求)。
  • 坑2:消息队列分区数量不足,导致吞吐量瓶颈,比如100个分区处理百万用户消息,每个分区压力过大,延迟增加。
  • 坑3:缓存策略不当,比如没有缓存击穿防护,热点弹幕(如“666”)导致数据库查询压力激增,影响系统性能。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1