对地图函数进行Flink两阶段提交,以实现完全一次的语义

背景

我们有一个Flink管道,该管道由多个源,多个接收器和沿该管道的多个运算符组成,还可以更新数据库。

为了这个问题并使它更简单,我们假设我们有一个看起来像这样的管道:

Source -> KeyBy -> flatMap -> Filter -> Sink

该管道应该允许我们侦听有关某些数据更改的通知。 (每个通知包含一个ID)对于每个通知,我们从数据库读取数据,运行算法并更新同一数据库行。此后,我们还发出数据变化的幅度。仅当数据变化幅度足够大时,我们才会向另一个Kafka主题发出通知。

  • 源订阅了Kafka主题,以侦听有关已更改的数据ID的通知。
  • KeyBy通过ID进行键控,以确保相同的ID不会同时被2个运算符实例处理。
  • 给出ID后,flatMap从数据库读取数据,运行算法并更新同一数据库行。它发出变化幅度。它是flatMap而不是Map,因为在某些情况下我们不希望发出任何变化幅度,例如,如果我们有一些特定的错误。
  • 过滤器过滤流的幅度小于某个阈值
  • 接收器将已过滤的通知发送到另一个Kafka主题。

问题:

我们想使用一次精确语义运行管道。 从我们所看到的,Flink为Kafka源,Kafka接收器以及中间的有状态或状态运算符支持一次语义。我们找不到任何地方可以解释如何对沿管道更新的资源进行一次准确的处理。 有一个TwoPhaseCommitSinkFunction可以创建一个接收器函数,该接收器函数只允许一次语义。

我们无法使用它,因为我们要更新数据库,然后向Kafka发出更改通知。在2个单独的接收器中执行此操作将创建竞争条件,在该条件下,我们可以在实际更新数据库之前收到幅度通知。

我们错过了什么吗?有没有办法在Map / flatMap运算符中实现两阶段提交?还有其他解决方案吗?

谢谢!

zhouzhou99 回答:对地图函数进行Flink两阶段提交,以实现完全一次的语义

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3168539.html

大家都在问