【问题标题】:Backfill Beam pipeline with historical data使用历史数据回填 Beam 管道
【发布时间】:2021-05-11 06:15:46
【问题描述】:

我有一个 Google Cloud Dataflow 管道(使用 Apache Beam SDK 编写),它在正常操作模式下处理发布到 Cloud Pub/Sub 的事件数据。

为了使管道状态保持最新并创建正确的输出,必须首先处理大量历史事件数据。此历史数据可通过 JDBC 获得。在测试中,我可以使用JdbcIO.Read PTransform 来读取和处理所有历史状态,但我想使用这个 JDBC 事件数据初始化我的生产管道,然后干净地转换为从 Pub/Sub 读取事件。如果管道逻辑以向后不兼容的方式发生更改,将来可能会再次发生相同的过程。

请注意,在发生这种历史读取时,新事件会继续到达 Pub/Sub(这些事件也最终会进入数据库),因此应该从仅从 JDBC 读取的历史事件中进行干净的转换,并且仅从 Pub/Sub 读取的较新事件。

我考虑过的一些方法:

  1. 有一个从两个输入中读取数据的管道,但在某个时间戳之前从 JDBC 过滤数据,在某个时间戳之后从 pub/sub 过滤数据。一旦管道被赶上,部署一个删除 JDBC 输入的更新。

    我认为这不会起作用,因为删除 I/O 转换不向后兼容。或者,管道的 JDBC 部分必须永远留在那里,无缘无故地消耗 CPU 周期。

  2. 编写一次性作业,用全部历史数据填充 pub/sub,然后启动仅从 pub/sub 读取的主管道。

    这似乎使用了比必要更多的发布/订阅资源,而且我认为管道中的新数据与更旧的数据交错会导致水印过早推进。

  3. 选项 #2 的变体——在处理历史数据之前停止创建新事件,以避免弄乱水印。

    这需要停机。

将历史数据回填到管道中似乎是一种常见要求,但我一直无法找到解决此问题的好方法。

【问题讨论】:

    标签: apache-beam google-dataflow


    【解决方案1】:

    您的第一个选项,从有界源(过滤到时间戳 截止)读取应该效果很好。

    因为 JDBC.Read() 是一个有界源,它将读取所有数据然后“完成”,即不再产生任何数据,将其水印推进到 +infinity,并且不再被调用(所以不用担心关于它消耗 CPU 周期,即使它存在于您的图表中)。

    【讨论】:

    • 从 JDBC 读取时,所有时间戳默认为 -infinity。计时器是如何使用的?
    • 我正在研究 Google Dataflow 支持的一些问题,但我认为这些问题与一般方法无关,这似乎应该可行。谢谢。
    猜你喜欢
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    相关资源
    最近更新 更多