Apache flink Flink两阶段提交,用于映射函数实现精确的一次语义

Apache flink Flink两阶段提交,用于映射函数实现精确的一次语义,apache-flink,two-phase-commit,exactly-once,Apache Flink,Two Phase Commit,Exactly Once,背景: 我们有一个Flink管道,它由多个源、多个汇和管道沿线的多个操作员组成,这些操作员还更新数据库 为了解决这个问题并使之更简单,让我们假设我们有一条管道,看起来是这样的: Source -> KeyBy -> FlatMap -> Filter -> Sink 这个管道应该允许我们监听有关某些数据更改的通知。(每个通知包含一个ID)对于每个通知,我们从数据库读取数据,运行算法并更新相同的数据库行。在那之后,我们还发出数据变化的幅度。只有当数据变化幅度足够大时,我们

背景:

我们有一个Flink管道,它由多个源、多个汇和管道沿线的多个操作员组成,这些操作员还更新数据库

为了解决这个问题并使之更简单,让我们假设我们有一条管道,看起来是这样的:

Source -> KeyBy -> FlatMap -> Filter -> Sink
这个管道应该允许我们监听有关某些数据更改的通知。(每个通知包含一个ID)对于每个通知,我们从数据库读取数据,运行算法并更新相同的数据库行。在那之后,我们还发出数据变化的幅度。只有当数据变化幅度足够大时,我们才会向另一个卡夫卡主题发出通知

  • 源订阅Kafka主题以侦听关于更改的数据ID的通知
  • KeyBy是通过ID进行键控,以确保同一ID不会被两个运算符实例同时处理
  • 给定ID,FlatMap从DB读取数据,运行算法并更新同一DB行。它发出变化幅度。这是一个平面图,而不是一个图,因为在某些情况下,我们不想发出任何变化幅度,例如,如果我们有一些特定的错误
  • 过滤器过滤流中小于某个阈值的量级
  • 接收器正在将过滤后的通知发送到另一个卡夫卡主题
问题:

我们希望使用一次语义来运行管道。 从我们所看到的,FLink支持卡夫卡源、卡夫卡接收器和中间状态或状态操作符的一次语义。我们找不到任何地方解释如何使用管道中更新的资源执行一次完全相同的操作。 有一个函数允许创建一个sink函数,该函数允许只使用一次语义

我们无法使用它,因为我们希望更新数据库,然后向Kafka发出更改通知。在两个单独的接收器中执行此操作将创建竞态条件,在DB实际更新之前,我们可以收到一个量级通知

我们错过什么了吗?有没有办法在Map/FlatMap操作符中实现两阶段提交?还有别的解决办法吗


谢谢

你读过这篇@MIkCode的帖子吗?是的,它只讨论了一次Flink的源、目标和状态。它没有提到内部操作符(如Map/flatmap)中使用的外部资源。你读过这篇文章吗@MIkCode是的,它只谈到了一次Flink源、目标和状态。它没有讨论内部操作符(如Map/FlatMap)中使用的外部资源