Flink和SparkStreaming中检查点机制的差异

时间:2017-12-12 09:10:14

标签: spark-streaming apache-flink kafka-consumer-api

使用来自Kafka主题的数据,Flink和SparkStreaming都提供了检查点机制,前提是auto.commit.enabled设置为false Spark文档说:

  

Spark输出操作至少一次。因此,如果您想要等同于完全一次的语义,则必须在幂等输出之后存储偏移量,或者在原子事务中与输出一起存储偏移量。

Flink docs 说:

  

启用Flink的检查点后,Flink Kafka Consumer将使用主题中的记录,并以一致的方式定期检查其所有Kafka偏移以及其他操作的状态。如果作业失败,Flink会将流程序恢复到最新检查点的状态,并从检查点中存储的偏移量开始重新使用Kafka的记录。

阅读其他来源我猜Flink Checkpointing将保存程序的状态以及消耗偏移但Spark Checkpointing只是节省消耗的偏移量,因为Spark说:

  

Spark输出操作至少一次。

任何人都可以说,在从Kafka主题中读取数据时,有人能够达到完全一致的语义吗?

2 个答案:

答案 0 :(得分:0)

我认为这涵盖了您所寻找的内容:https://data-artisans.com/blog/high-throughput-low-latency-and-exactly-once-stream-processing-with-apache-flink

完全一次和至少一次之间的最大区别在于,确保一旦确保不输出重复数据。至少一次保证您不会丢失任何数据(完全相同),但可能会输出重复的数据。

修改

我应该提到我对Spark不如Flink那么熟悉,但这是Flink所涉及的一件大事,这就是我为它提供了大概述文档链接的原因。但是,确切一次与至少一次的概念是普遍的,而不是技术依赖的。

答案 1 :(得分:0)

  

谁能说出从Kafka主题中读取数据有何区别,以及如何达到精确语义一次?

仅在源代码一侧无法实现语义。恰好是一个概念,整个流应用程序都需要支持:

  • 您需要确保处理所有传入的数据点(至少一次)。这就是将源偏移量存储在检查点中时得到的结果。万一发生故障,您将重新读取相同的数据并重新处理在上次成功中断和故障期间丢失的所有内容。
  • 您的应用程序代码本身需要确保其之间进行的所有操作都是确定性的和幂等的。如果您在流式处理框架之外触发操作,则该操作将在恢复期间重新触发。恢复期间的计算必须保持一致。
  • 在恢复过程中将发出重复的输出。这是系统迫在眉睫的,在框架级别上无法避免。因此,对于仅一次的输出,您有三个选择:
    1. 将输出推迟到编写检查点之前,这是最简单且通用的解决方案,但当然会带来巨大的滞后。
    2. 使用幂等水槽。如果您写入KV存储并且从不更新任何值,则重复项将被隐式过滤。
    3. 使用事务接收器,其中重复项被过滤。 Flink和Kafka Streams就是这样写到Kafka主题中的。

要重申:在发生故障的情况下,总是需要多次读取数据,这就是为什么仅在源级别上一次仅有意义的原因。它需要在整个框架/应用程序中实现。

正确设置水槽是最难的部分。我猜Spark还不支持。对于Spark开发人员而言,可能会更困难,因为在每个提到的系统中实际采用检查点的方式不同。但是我的Spark(流媒体)知识已有一年多了,因此在这方面可能会不断发展。