flink和sparkstreaming都使用kafka主题中的数据,提供了检查点机制,前提是 auto.commit.enabled
设置为 false
. spark医生说:
Spark输出操作至少一次。因此,如果您想要完全等同于once语义,那么必须在幂等输出之后存储偏移量,或者在原子事务中与输出一起存储偏移量。
但Flink医生说:
启用flink的检查点后,flink kafka使用者将使用某个主题的记录,并以一致的方式定期检查其所有kafka偏移量以及其他操作的状态。如果作业失败,flink会将流程序恢复到最新检查点的状态,并从检查点中存储的偏移量开始重新使用kafka的记录。
阅读其他来源,我猜flink检查点将保存程序的状态以及消耗偏移量,但是spark检查点只保存消耗偏移量,因此spark说:
Spark输出操作至少一次。
有没有人能说一个人在阅读Kafka主题中的数据时有什么不同,以及他是如何做到一语双关的?
2条答案
按热度按时间6ss1mwsb1#
有没有人能说一个人在阅读Kafka主题中的数据时有什么不同,以及他是如何做到一语双关的?
只有在源代码端才能实现一次语义。只有一个概念,整个流媒体应用程序都需要支持:
您需要确保处理所有传入的数据点(至少一次)。这就是在检查点中存储源偏移量时得到的结果。如果发生故障,您将重新读取相同的数据,并重新处理上次成功停机和故障期间丢失的所有数据。
应用程序代码本身需要确保它在这两者之间所做的一切都是确定的和幂等的。如果在精简框架之外触发操作,则在恢复期间将重新触发此操作。在恢复过程中,计算需要保持一致。
恢复期间将发出重复输出。这是迫在眉睫的,在框架层面是无法避免的。因此,对于一次输出,您有三个选项:
延迟输出直到检查点被写入,这是最简单和通用的解决方案,但当然会引入一个巨大的延迟。
使用幂等sink。如果写入kv存储并且从不更新任何值,则会隐式过滤重复项。
使用事务接收器,在其中过滤重复项。这就是Flink和Kafka流写进Kafka主题的方式。
重申一下:在发生故障时,数据总是需要被多次读取,这就是为什么只有一次在源代码级别上是没有意义的。它需要为整个框架/应用程序实现。
把Flume弄好是最难的。我猜spark还不支持这一点。对于spark开发人员来说,这可能会更困难,因为在上述每个系统中实际采用的检查点方式不同。但我的spark(流媒体)知识已经有一年多的历史了,所以这方面可能会有持续的发展。
bxgwgixi2#
我想这包括了你要找的:https://data-artisans.com/blog/high-throughput-low-latency-and-exactly-once-stream-processing-with-apache-flink
“精确一次”和“至少一次”之间的最大区别在于,使用“精确一次”可以保证不会输出重复的数据。至少一次可以保证您不会丢失任何数据(与恰好一次相同),但可能会输出重复的数据。
编辑:
我应该提到的是,我对spark的熟悉程度不如我对flink的熟悉,但这是flink涉及的一个重要方面,这就是为什么我提供了它的大概述文档链接。但精确一次与至少一次的概念是普遍的,不依赖于技术。