我有一个 Google Cloud Dataflow 管道(使用 Apache Beam SDK 编写),它在正常操作模式下处理发布到 Cloud Pub/Sub 的事件数据。
为了使管道状态保持最新并创建正确的输出,必须首先处理大量历史事件数据。此历史数据可通过 JDBC 获得。在测试中,我可以使用JdbcIO.Read
PTransform 读取和处理所有历史状态,但我想使用此 JDBC 事件数据初始化我的生产管道,然后干净地转换为从 Pub/Sub 读取事件。如果流水线逻辑以向后不兼容的方式改变,那么同样的过程可能会在未来再次发生。
请注意,当这种历史读取发生时,新事件会继续到达 Pub/Sub(这些最终也会进入数据库),因此应该从仅从 JDBC 读取的历史事件和仅读取较新的事件进行干净的切换来自发布/订阅。
我考虑过的一些方法:
有一个从两个输入读取的管道,但在某个时间戳之前从 JDBC 过滤数据,在某个时间戳之后从 pub/sub 过滤数据。一旦管道被赶上,部署一个删除 JDBC 输入的更新。
我认为这不会起作用,因为删除 I/O 转换不向后兼容。或者,管道的 JDBC 部分必须永远留在那里,无缘无故地消耗 CPU 周期。
编写一次性作业,用全部历史数据填充 pub/sub,然后启动仅从 pub/sub 读取的主管道。
这似乎使用了比必要更多的发布/订阅资源,而且我认为在管道中交错的新数据与更旧的数据会导致水印过早推进。
选项 #2 的变体——在处理历史数据之前停止创建新事件,以避免弄乱水印。
这需要停机时间。
将历史数据回填到管道中似乎是一种常见要求,但我一直无法找到解决此问题的好方法。