Apache spark 在使用Kafka直接输入流和有状态流转换时,如何理解检查点恢复?

Apache spark 在使用Kafka直接输入流和有状态流转换时,如何理解检查点恢复?,apache-spark,spark-streaming,Apache Spark,Spark Streaming,在纱线集群上,我使用kafka directstream作为输入(例如,批处理时间为15s),并希望在单独的用户ID中聚合输入消息。 因此,我使用有状态的流式api,如updateStateByKey或mapWithState。但是从api源代码中,我看到mapWithState的默认检查点持续时间是batchduration*10(在我的例子中是150秒),而在kafka directstream中,分区偏移量是在每个批次(15秒)检查点。实际上,每个数据流可以设置不同的检查点持续时间。 所以

在纱线集群上,我使用kafka directstream作为输入(例如,批处理时间为15s),并希望在单独的用户ID中聚合输入消息。 因此,我使用有状态的流式api,如
updateStateByKey
mapWithState
。但是从api源代码中,我看到
mapWithState
的默认检查点持续时间是batchduration*10(在我的例子中是150秒),而在kafka directstream中,分区偏移量是在每个批次(15秒)检查点。实际上,每个数据流可以设置不同的检查点持续时间。 所以,我的问题是:

当流应用程序崩溃时,我重新启动它,卡夫卡偏移量和状态流rdd在检查点中是异步的,在这种情况下,我如何保持数据不丢失?还是我误解了检查点机制

如何保持数据不丢失

有状态流,如
mapWithState
updateStateByKey
要求您提供一个检查点目录,因为这是它们工作方式的一部分,它们在每个中间存储状态,以便能够在崩溃时恢复状态

除此之外,链中的每个
DStream
也可以自由请求检查点,问题是“您真的需要检查其他流吗”


如果应用程序崩溃,Spark会获取存储在检查点内的所有状态RDD,然后将其带回内存,这样您的数据就和Spark上次检查时的数据一样好。我要记住的一件事是,如果您更改了应用程序代码,您无法从检查点恢复状态,您必须将其删除。这意味着,例如,如果您需要进行版本升级,则以前存储在该状态中的所有数据都将消失,除非您以允许版本控制的方式手动保存这些数据。

感谢您的回复:)在我的情况下,我在应用程序版本更新时已处理过该情况。但我真正想知道的是:例如,开始时间为0s,批处理时间为15s,mapWithState检查点间隔为150s。因此,如果流媒体应用程序在200s崩溃,在不重新编译的情况下重新启动时,状态流恢复到数据为150s,卡夫卡偏移记录恢复到时间为195s。我是否在165s、180s丢失卡夫卡输入数据?如果为真,我怎么能避免呢?谢谢~@HengSu如果检查点在150秒,那么当你恢复时,它会从150秒开始重新开始。这意味着您可能会处理已经处理的数据,但检查点就是这样工作的。卡夫卡偏移量也存储在检查点数据中。@Yuval Itzchakov抱歉,我有点困惑。卡夫卡偏移量每批(15秒)检查一次对吗?当MapWithStateDStream在150秒恢复到数据时,你的意思是卡夫卡偏移量也恢复到195秒以外的150秒吗?所以我没有丢失数据,只要再加工几批就行了?@HengSu,没错因此,在第二种方法中,我们使用不使用Zookeeper的简单Kafka API。偏移量由检查点内的火花流跟踪。这消除了Spark流媒体和Zookeeper/Kafka之间的不一致性)