跳到主要内容

如何设计一个 100W 用户同时在线的弹幕系统

行业案例:shopee 70W人在线的 弹幕 系统,是怎么架构的?

https://www.cyningsun.com/03-31-2019/live-streaming-danmaku.html

100W 用户在线, 3s 促达一次(将 3s 内的弹幕推送至用户)。 即 33w QPS 。

压力

  • 带宽,33w QPS 的带宽是很大的
  • 弱网环境
  • 性能与可靠性

架构设计思路

  • 业务解耦 + 服务拆分
    • 将弹幕系统拆分为 2 个服务,发送弹幕(逻辑复杂,调用少)、弹幕拉取(逻辑简单,调用高)
  • 本地缓存,优化高并发读
    • 弹幕拉取服务,RPC 定时拉取数据,缓存至内存,后续请求到弹幕拉取服务时,直接走内存 (把数据放到离用户最近的地方
    • 本地缓存非常重要,推荐开源缓存框架 caffeine
  • 限流,优化高并发写
    • 发送弹幕限流(有选择丢弃多余的弹幕)
  • 滑动窗口,实现无锁化读写
    • 弹幕根据时间进行分片(按照秒数进行分片,只保留 60s 的数据)
    • 根据请求时间戳,获取弹幕(30s 内的数据)
  • 短轮训实现弹幕促达(推送 vs 拉取? 长轮训 vs 短轮训?)
    • 长轮训、websocket(推送) 不适用弱网环境
    • 采用短轮询
  • 传输优化、节约带宽
    • http gzip 压缩
    • 结构体简化
    • 请求频率控制

推送 vs 拉取, 长轮询 vs 短轮询

推送 push

服务器主动将数据推送至客户端,优点是实时性强,缺点是,服务器需要保持大量的长连接。

  • websocket 双向
  • SSE,单向
  • 消息队列

拉取 pull

客户端主动向服务器请求数据,优点是,客户端控制请求时机,简单可靠。

  • HTTP 请求

长轮询 Long Polling

客户端通过一个长连接请求服务器(发送请求到服务器之后,不断开连接,直到有数据,或者到了超时时间)

  • Ajax Long Polling, 开启 http 的 keep-alive

短轮询 Short Polling

客户端频繁的请求服务器。使用的技术与长轮询一致,只是参数不同而已。