通过 Google 云 Pub/Sub 将数据重播到 Apache Beam 管道中,而不会使其他订阅者超载

Replaying data into Apache Beam pipeline over Google Cloud Pub/Sub without overloading other subscribers

我在做什么: 我正在构建一个系统,其中一个 Cloud Pub/Sub 主题将由数十个 Apache Beam 管道以流模式读取。每次部署新管道时,它应该首先处理几年的历史数据(存储在 BigQuery 中)。

问题: 如果我在部署新管道时将历史数据重播到主题中(如建议的那样 here), it will also be delivered to every other pipeline currently reading the topic, which would be wasteful and very costly. I can't use Cloud Pub/Sub Seek (as suggested here) as it stores a maximum of 7 days history (more details here)。

问题:以最小的开销(并且不会导致事件 time/watermark 问题)将历史数据重播到新的 Apache Beam 流管道的推荐模式是什么?

目前的思路:目前能想到三种解法,但是none好像很优雅,没见过在文档、常见模式 (part 1 or part 2) 或其他地方提到。他们是:

  1. 理想情况下,我可以使用 Flatten to merge the real-time ReadFromPubSub with a one-off BigQuerySource, however, I see three potential issues: a) I can't account for data that has already been published to Pub/Sub, but hasn't yet made it into BigQuery, b) I am not sure whether the BigQuerySource might inadvertently be rerun if the pipeline is restarted, and c) I am unsure whether BigQuerySource works in streaming mode (per the table here).

  2. 我为每个管道创建一个单独的重播主题,然后使用 Flatten 合并主要主题和管道特定重播主题的 ReadFromPubSub。部署管道后,我将历史数据重播到特定于管道的重播主题。

  3. 我为每个管道创建了专门的主题,并部署了一个单独的管道来读取主要主题并将消息广播到特定于管道的主题。每当需要重播时,我都可以将数据重播到特定于管道的主题中。

在你的三个想法中:

  • 第一个将不起作用,因为目前 Python SDK 不支持从有界源进行无界读取(这意味着您不能将 ReadFromBigQuery 添加到流管道)。

  • 第三个听起来过于复杂,而且可能成本很高。

我相信你目前最好的选择是如你所说,将你的 table 重播到一个额外的 PubSub 主题中,你正确地指出了你的主要主题。

我会检查是否有更好的解决方案,但目前,选项 #2 应该可以解决问题。


此外,我建议您参考 interesting talk from Lyft on doing this for their architecture(在 Flink 中)。