大规模实时流计算的系统设计 - Kashyap


使用 Spring、Pub/Sub、Dataflow、Redis、Reentrant Lock 模式和 guava 缓存构建实时视图计数服务以处理 20k tps 规模。


系统架构
对于任何现场表演,观看直播用户收视率是一个重要指标,它是通过比较不同类型节目的直播数据来提供:参与度、节目或创作者受欢迎程度、最新市场趋势的指标。
由于这是一个重要的指标,我们决定实现这一目标的后端服务必须具有以下特征

  • 异步
  • 自动扩展
  • 高可用性
  • 处理流行/名人节目的间歇性峰值
  • 低延迟
  • 可靠(不应错过/丢弃任何事件)

整体架构的设计牢记上述 SLA,我们将分两个阶段详细讨论每个方面。
  • 将流数据处理为用户加入事件(接收事件→转换和聚合事件→存储短期(Redis)和长期(Db))。
  • 以 20k tps处理来自各种来源(网络、移动设备、电视)的获取实时计数请求。



执行
将流数据处理为用户加入事件
设计决策

  • PubSub vs Apache Kafka:我们遵循事件驱动的架构,这两种技术同样能够满足要求。Confluent Kafka 和Pub-Sub 都是托管服务,并根据需求提供水平扩展,如果您有任何特定用例,请查看博客比较各种消息队列。
  • Dataflow vs Spark 或 Flink:由于事件的规模非常大,我们需要一些平台来读取、转换、聚合事件数据并减少后端服务器上的流量。我们选择 Dataflow 作为我们的数据处理服务 Spark 或 Flink 也可以满足要求,但由于 Dataflow 的模型基于Apache Beam,它为流式传输和批处理数据带来了统一的解决方案。Beam 与运行时无关的特性使得将来也可以切换到 Apache Flink 或 Spark 执行环境。


事件流程

  1. 在后端服务器上接收来自各种来源(Web/移动/电视)的用户事件。
  2. 一旦收到事件并通过 sha256 验证签名,它们就会被推送到 Pub-Sub 主题。
  3. Dataflow 是主题的订阅者,并设置了管道以读取、转换、聚合事件并将结果写入接收器(Db/Queue/blob)。在这里,我们将其推送到不同的 Pub-Sub 主题。
  4. 在更广泛的层面上,下面显示的管道中正在发生两件事。 -聚合用户事件:至于可靠性源可以发送多个需要忽略或聚合为一个事件的事件。 -每个节目的聚合事件:一旦用户事件被聚合,我们将再次聚合每个节目的所有用户加入事件以获取用户观看次数。
  5.  一旦将数据写入 Pub-Sub 主题,它就会在我们的后端服务器上接收,因为它已经订阅了 sink Pub-Sub 主题。
  6.  收到结果后,将其存储在 Redis 缓存中,并在一定时间间隔后存储在持久性存储(PostgreSQL)中。

获取实时计数请求的处理
设计决策

  • Push vs Pull:我们遵循 KISS 设计原则,采用基于 pull 的模型,而 push 模型将计数数据通知给数百万用户会浪费资源,产生巨大的成本,最重要的是会使系统过于复杂。
  • 多线程与可重入锁:要使用多线程处理 20k tps,假设从 redis 获取计数数据的响应时间为 50 毫秒,我们将需要 (20k/50) 400 个线程/秒。在任何时候使用可重入锁机制,只有一个线程将获取锁以获取实时计数数据,将计数减少到 1 个线程/秒,其余线程将返回最后更新的值。正如您所看到的,使用可重入锁有助于有效地利用资源,从而更清楚地阅读(哲学家就餐问题——维基百科



决策树
我们有几个来源使用我们的服务并定期刷新结果,从而增加了流量(~20K tps)并需要有效的处理。

  • 一旦在后端收到获取实时用户计数的 Get 请求,我们首先检查任何缓存的数据本地 guava 缓存,如果存在则返回数据。
  • 一旦缓存数据过期(10 秒过期),任何新请求都会有缓存未命中。next 将检查是否已在资源上获取任何锁(通道:节目的逻辑标识符)。
  • 如果是,则返回最后更新的数据,否则在任何时候只有一个线程将获取特定资源(通道)上的锁并获取数据,所有其他线程都会立即释放缓存数据或最后更新的数据。
  • 一旦获得锁的线程接收到来自 Redis 缓存的数据,它就会更新本地缓存并释放锁。
  • 正如您所看到的,使用上述锁定机制可以有效地使用 CPU 和内存。除了实时用户计数,相同的架构可用于表情符号计数、实时投票、民意调查、测验、实时记分卡等。

影响
该系统的设计、构建和测试旨在处理超大规模的流量,并在 6 月 3 日至 5 日举行的 GLF(Glance Live Fest)活动期间进行了测试,现场直播的每日活跃用户为 1000 万,并且表现异常出色没有任何错误或停机时间。