Apache Flink 中端到端的 Exactly-once 处理

End-to-end Exactly-once processing in Apache Flink

Apache Flink 通过从检查点恢复作业来保证在失败和恢复时仅处理一次,检查点是分布式数据流和操作员状态的一致快照(分布式的 Chandy-Lamport 算法快照)此保证在故障转移时恰好一次。

在集群正常运行的情况下,Flink如何保证exactly once processing,比如给定一个Flink source,从外部source(比如Kafka)读取,Flink如何保证事件从source读取一次?事件源和 Flink 源之间是否存在任何类型的应用程序级别确认?另外,Flink如何保证事件从上游算子到下游算子只传播一次呢?这是否也需要对接收到的事件进行任何类型的确认?

Flink 不保证每个事件都从源中读取一次。相反,它保证每个事件只影响托管状态一次。

检查点包括源偏移量,并且在检查点恢复期间,源会被倒回并且一些事件可能会被重播。这很好,因为检查点包括整个作业的状态,这些状态是从读取所有内容到存储在检查点中的偏移量而产生的,并且没有超出这些偏移量的内容。

因此 Flink 的 exactly once 保证需要可重放的源。运营商之间的 Exactly once 消息传递取决于 tcp。

保证接收器不会收到重复的结果还需要事务接收器。 Flink 提交事务作为检查点的一部分。