Apache Flink - 如何在下游故障时停止和恢复流处理

Apache Flink - how to stop and resume stream processing on downstream failure

我有一个 Flink 应用程序,它使用具有多个分区的 Kafka 主题上的传入消息,进行一些处理,然后将它们发送到接收器,接收器通过 HTTP 将它们发送到外部服务。有时下游服务中断,流处理需要停止,直到它恢复运行。

我正在考虑两种方法。

  1. Http 接收器发送输出消息失败时抛出异常。这将导致任务和作业根据配置的重启策略重启。最终下游服务会恢复,系统会从中断处继续。
  2. 让 Sink 休眠并在失败时重试;它可以持续执行此操作,直到下游服务恢复。

根据我的理解和我的 PoC,1。我将失去 exactly-least-once 保证,因为接收器本身是外部状态。据我所知,您不能使简单的 HTTP 端点具有事务性,因为它需要实现 TwoPhaseCommitSinkFunction。

对于 2. 这不是一个问题,因为在接收器成功写入之前管道不会继续,我可以依靠整个系统的背压来暂停从 Kafka 源检索消息。

我的主要问题是:

  1. 不能为简单的 HTTP 端点创建 TwoPhaseCommitSinkFunction 的假设是否正确?
  2. 两种策略中哪一种最有意义?
  3. 我是否缺少更简单明显的解决方案?

我认为你可以在 Flink 中尝试 AsyncIO - https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/operators/asyncio/

尝试让 HTTP 端点在为请求完成所有操作后发送响应,例如在http服务器中,请求的处理已经完成,结果已经提交给DB。然后在 AsyncIO 运算符中使用 http 异步客户端。 AsyncIO 运算符将等待,直到运算符收到响应。如果发生任何错误,Flink streaming pipeline 将失败并根据恢复策略重新启动管道。

所有未收到响应的 HTTP 端点请求都将在 AsyncIO 操作符的内部缓冲区中,一旦流式传输管道失败,缓冲区中待处理的请求将保存在检查点状态中。当内部缓冲区已满时,它也会触发背压。