排空管道会触发对出现故障的元素的PubSub的确认吗?

时间:2019-05-15 15:15:41

标签: apache-beam google-cloud-pubsub spring-cloud-dataflow

我在Apache Beam 2.5中有一个流水管道,该流水管道订阅了PubSub订阅,解析了从该订阅作为消息接收的CSV文件,对数据进行了一些琐碎的处理,然后将结果存储在BigQuery中。

有时,发送给PubSub主题的数据的生产者会在不通知我们的情况下更改CSV文件格式(添加/删除/重命名列)。发生这种情况时,幸运的是CSV解析DoFn开始失败,并且管道卡住,无法重试该元素(管道的系统滞后开始单调增加)。

Google的文档促进了使用“排水”功能作为停止管道的“不错”方法,并概述了“飞行中”元素不会冒丢失的危险。这是否意味着所有飞行中的元素,即使是发生故障的元素,在其束关闭时也会被“提交”,从而触发对PubSub的ACK?

就我而言,我希望不对失败的元素进行确认,以便在修复管道之后,重新传送失败的元素后将对其进行处理。

2 个答案:

答案 0 :(得分:1)

另一个回答者将一个问题与一个流行的(虽然尚未被接受)答案联系起来,该答案指出 Dataflow 将确认消息一次,对于消息所属的包,“包的结果(输出和状态突变等)已经持久承诺”(At what stage does Dataflow/Apache Beam ack a pub/sub message?)。

请务必注意,当您的管道中存在有状态操作时,Dataflow 需要提交状态。例如,对于窗口化,Dataflow 需要在等待窗口通过时将您的数据存储在某处,此时它会将状态拉回并将其发送到管道的下一部分。

这种行为实际上与我几年来在生产中使用 Dataflow 观察到的行为相符。我们曾经有一个无状态管道(没有窗口等),当管道的任何部分发生异常时,它都会拒绝消息。当我们添加窗口时,我们注意到它会确认消息,即使消息所属的窗口还没有通过(并且在管道末端没有任何东西输出到接收器中)。

因此,在具有状态操作的管道中,即使消息是“坏的”消息也会被确认 的情况,因为消息不会被视为您的代码“坏”,直到它被确认后才能持久提交。这种情况不会发生,如果您的管道没有有状态操作(并且所有无状态操作在您为 Pub/Sub 订阅配置的 ACK 截止日期内完成),您可以安全地依赖 NACK 来处理这些“坏”消息.

如果这对您来说是个问题,因为您的管道中有有状态的操作,我建议您采取以下两种方式之一:

  • 在发布 Pub/Sub 消息之前添加验证,以免“坏”消息进入您的管道,或
  • 将您的管道分成两个管道,一个是无状态管道,一个是有状态管道,这样消息只会在第一个管道中被视为“坏”,并且可以在管道更新后不再认为消息“坏”时重试" 或者在不需要的情况下通过其他方式丢弃该消息

答案 1 :(得分:0)

根据一些相关的讨论[1],仅当捆绑成功时才会发生短接。在您的情况下,捆绑包已经失效,这意味着它在耗尽之前不会成功,我认为我们不希望遇到麻烦。

[1] At what stage does Dataflow/Apache Beam ack a pub/sub message?