如何保存Spark消耗给ZK或Kafka的最新偏移量,并在重启后可以回读

时间:2015-08-06 04:04:20

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

我正在使用Kafka 0.8.2从AdExchange接收数据,然后我使用Spark Streaming 1.4.1将数据存储到MongoDB

我的问题是当我重新启动Spark Streaming作业时,例如更新新版本,修复错误,添加新功能。它将继续阅读当前offset的{​​{1}},然后在重新启动作业期间,我将丢失数据AdX推送到kafka。

我尝试类似kafka的内容,但会收到0 - >最后,数据是巨大的,并在数据库中重复。

我也尝试将特定的auto.offset.reset -> smallestgroup.id设置为consumer.id,但它也一样。

如何保存Sparkoffset消耗的最新zookeeper点火,然后可以将其读回到最新的kafka

4 个答案:

答案 0 :(得分:15)

createDirectStream函数的一个构造函数可以获取一个映射,该映射将分区id作为键,并将您开始使用的偏移量作为值。

在这里看看api:http://spark.apache.org/docs/2.2.0/api/java/org/apache/spark/streaming/kafka/KafkaUtils.html 我所谈论的地图通常称为:fromOffsets

您可以将数据插入地图:

startOffsetsMap.put(TopicAndPartition(topicName,partitionId), startOffset)

在创建直接流时使用它:

KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder, (String, String)](
                streamingContext, kafkaParams, startOffsetsMap, messageHandler(_))

每次迭代后,您都可以使用以下方法获取已处理的偏移量:

rdd.asInstanceOf[HasOffsetRanges].offsetRanges

您将能够使用此数据在下一次迭代中构建fromOffsets映射。

您可以在此处查看完整的代码和用法:页面末尾的https://spark.apache.org/docs/latest/streaming-kafka-integration.html

答案 1 :(得分:2)

要添加到Michael Kopaniov的答案中,如果您真的想将ZK用作存储和加载偏移地图的地方,您可以。

但是,因为你的结果没有输出到ZK,所以除非你的输出操作是幂等的(听起来不是这样),否则你将无法获得可靠的语义。

如果可以将结果与mongo中的同一文档一起存储在单个原子动作中的偏移量中,那么对您来说可能更好。

有关详细信息,请参阅https://www.youtube.com/watch?v=fXnNEq1v3VA

答案 2 :(得分:1)

以下是一些可用于在ZK http://geeks.aretotally.in/spark-streaming-kafka-direct-api-store-offsets-in-zk/

中存储偏移量的代码

当您调用KafkaUtils.createDirectStream时,可以使用以下代码来使用偏移量: http://geeks.aretotally.in/spark-streaming-direct-api-reusing-offset-from-zookeeper/

答案 3 :(得分:-1)

我还没有100%想到这一点,但最好的办法是设置JavaStreamingContext.checkpoint()。

有关示例,请参阅https://spark.apache.org/docs/1.3.0/streaming-programming-guide.html#checkpointing

根据一些博客条目 https://github.com/koeninger/kafka-exactly-once/blob/master/blogpost.md ,有一些警告,但它几乎感觉它涉及某些仅仅提到并且没有实际解释的边缘情况。