Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 如何将Spark消耗的最新偏移量保存到ZK或Kafka,并在重新启动后读取_Apache Spark_Apache Kafka_Spark Streaming_Kafka Consumer Api - Fatal编程技术网

Apache spark 如何将Spark消耗的最新偏移量保存到ZK或Kafka,并在重新启动后读取

Apache spark 如何将Spark消耗的最新偏移量保存到ZK或Kafka,并在重新启动后读取,apache-spark,apache-kafka,spark-streaming,kafka-consumer-api,Apache Spark,Apache Kafka,Spark Streaming,Kafka Consumer Api,我使用Kafka 0.8.2从AdExchange接收数据,然后使用Spark Streaming 1.4.1将数据存储到MongoDB 我的问题是当我重新启动我的Spark Streaming工作时,比如更新新版本、修复bug、添加新功能。在重新启动作业期间,它将继续读取卡夫卡的最新偏移量,然后我将丢失数据AdX推送到卡夫卡 我尝试了一些类似于auto.offset.reset->minimate的方法,但它将从0->上一次接收到大量数据,并且在db中重复 我还尝试将specificgroup

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

我的问题是当我重新启动我的
Spark Streaming
工作时,比如更新新版本、修复bug、添加新功能。在重新启动作业期间,它将继续读取卡夫卡的最新偏移量,然后我将丢失数据AdX推送到卡夫卡

我尝试了一些类似于
auto.offset.reset->minimate
的方法,但它将从0->上一次接收到大量数据,并且在db中重复

我还尝试将specific
group.id
consumer.id
设置为
Spark
,但它是相同的


如何将消耗的最新
偏移量
spark保存到
zookeeper
kafka
中,然后可以从中读回最新的
偏移量

createDirectStream函数的一个构造函数可以获得一个映射,该映射将保存分区id作为键,并将开始消耗的偏移量作为键价值观

请看这里的api: 我所说的地图通常叫做:fromOffset

您可以将数据插入地图:

startOffsetsMap.put(TopicAndPartition(topicName,partitionId), startOffset)
并在创建直接流时使用它:

KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder, (String, String)](
                streamingContext, kafkaParams, startOffsetsMap, messageHandler(_))
每次迭代后,可以使用以下方法获得处理后的偏移:

rdd.asInstanceOf[HasOffsetRanges].offsetRanges
您将能够在下一次迭代中使用此数据来构建fromOffsets映射


您可以在这里看到完整的代码和用法:在页面末尾,我还没有100%地解决这个问题,但您最好的办法可能是设置JavaStreamingContext.checkpoint()

有关示例,请参见


根据一些博客文章,有一些警告,但它几乎感觉它涉及到某些边缘情况,这些情况只是暗示,而不是实际解释。

要补充迈克尔·科帕尼奥夫的答案,如果你真的想使用ZK作为存储和加载偏移地图的地方,你可以

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

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


有关更多详细信息,请参见以下代码,您可以使用这些代码在ZK中存储偏移

下面是一些代码,您可以在调用KafkaUtils.createDirectStream时使用偏移量:

但如何将消耗的最新偏移量保存到ZK或Kafka。我尝试启用
kafkaParams++=Map[String,String](“auto.commit.interval.ms”->“1000”)kafkaParams++=Map[String,String](“zookeer.sync.time.ms”->“200”)kafkaParams++=Map[String,String](“zookeer.session.timeout.ms”->“400”)
但这不是我告诉您的使用.offsetRanges数据结构的选项之一。在给定的迭代中处理流之后,您可以执行:
dStream.foreachRDD{rdd=>val x=rdd.asInstanceOf[HasOffsetRanges].offsetRanges;//使用x执行某些操作(例如保存外部FS)}
x将为rdd的每个主题分区组合保存最后处理的偏移量。如果你需要一次语义,你必须手动支持它,但这是可能的。我的想法是我不想保存在外部存储中,因为ZK和Kafka可以处理这个问题。我相信他们不能。Spark 1.3.1将其关于如何使用Kafka作为数据源的方法从预写日志更改为直接流。Direct stream使用Kafka SimpleConsumer从Kafka获取消息。您可以在这里阅读:使用SimpleConsumer的缺点之一是您必须跟踪自己已经消耗的偏移量。只要Spark streaming使用简单的消费者,您就不会从Kafka/ZK的角度找到解决方案。但是Spark可能会在卡夫卡的基础上增加自己的操控性。任何可靠的存储设备都应该可以完成这项工作。我通常将数据保存到HDFS,因为我认为这是最简单的解决方案。我想不出Redis为什么不能做这项工作的原因。检查点是正确的方法,以防您不更改您的StreamingContext,因为这样您就可以从正确的偏移量自动继续处理(Spark将负责)。如果您想添加功能/纠正错误(显然giaosudau也想这么做),那么您经常会更改流上下文,因此无法使用checkpoints目录。您提供的最后一个链接对此进行了完美的解释。@MichaelKopaniov是否有任何方法可以对上下文函数进行校验和,并在函数发生更改时使以前的上下文无效?在这种情况下,它将返回到从存储读取偏移量(fs,数据库)@Stephane自从我处理这个问题以来,几天过去了,所以我可能弄错了,但据我记忆中的旧Spark streaming(@Stephane但您可以做的是使用一些可配置参数,指示您是要使用检查点目录中的流式上下文,还是要创建自己的新上下文。如果此参数指定您要创建新上下文,则您将从(fs,数据库)创建If并在将数据检查点到检查点目录时覆盖上一个上下文。不同-来自文档:"如果启用Spark检查点,偏移量将存储在检查点中。这很容易启用,但也有缺点。您的输出操作必须是幂等的,因为您将获得重复的输出;事务不是选项。此外,如果应用程序代码已更改,则无法从检查点恢复。对于计划的升级,请您可以通过在旧代码的同时运行新代码来缓解这种情况(因为输出无论如何都需要是幂等的,所以它们不应该冲突)