Spark结构化流式传输查询始终以auto.offset.rest = earliest开头,即使设置了auto.offset.reset = latest

时间:2018-02-14 23:19:58

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

我尝试使用Spark结构化流媒体从Kafka读取数据时遇到了一个奇怪的问题。 我的用例是能够从可用的最大/最新偏移量中读取主题。

我的阅读配置:

val data = spark
     .readStream
     .format("kafka")
     .option("kafka.bootstrap.servers", "some xyz server")
     .option("subscribe", "sampletopic")
     .option("auto.offset.reset", "latest")
     .option("startingOffsets", "latest")
     .option("kafkaConsumer.pollTimeoutMs", 20000)
     .option("failOnDataLoss","false")
     .option("maxOffsetsPerTrigger",20000)
     .load()

我的写作配置:

data
    .writeStream
    .outputMode("append")
    .queryName("test") 
    .format("parquet")
    .option("checkpointLocation", "s3://somecheckpointdir")
    .start("s3://outpath").awaitTermination()

使用的版本:

  • spark-core_2.11 : 2.2.1
  • spark-sql_2.11 : 2.2.1
  • spark-sql-kafka-0-10_2.11 : 2.2.1

我已经在线完成了我的研究,并从[Kafka文档](https://kafka.apache.org/0100/documentation.html0/

开始

我正在使用新的消费者api并且正如文档建议的那样我只需要将auto.offset.reset设置为“latest”或者startOffsets设置为“latest”以确保我的Spark作业开始消耗每个可用的最新偏移量在卡夫卡分区。

我也知道设置auto.offset.reset仅在第一次启动新查询时启动,而不是在重新启动应用程序时启动,在这种情况下,它将继续从上次保存的偏移读取。

我正在使用s3来检查我的偏移量。我看到它们是在s3:// somecheckpointdir下生成的。

我面临的问题是Spark作业始终从最早的偏移读取,即使在第一次启动应用程序的启动期间在代码中指定了最新选项,我在Spark日志中看到了这一点。 正在使用auto.offset.reset = earliest。我没有看到与此特定问题相关的帖子。

我想知道我是否在这里遗漏了一些东西,如果有人之前已经看过这种行为。任何帮助/方向确实有用。谢谢。

4 个答案:

答案 0 :(得分:3)

  1. 所有Kafka配置都应使用kafka.前缀设置。因此,正确的选项键是kafka.auto.offset.reset
  2. 你永远不应该设置auto.offset.reset。相反,“设置源选项startingOffsets以指定从哪里开始。结构化流式传输管理内部消耗的偏移,而不是依靠kafka Consumer来执行此操作。这将确保在新主题时不会遗漏任何数据/ partitions是动态订阅的。注意startingOffsets仅在启动新的流式查询时适用,并且恢复将始终从查询中断的地方开始。“ [1]
  3. [1] http://spark.apache.org/docs/latest/structured-streaming-kafka-integration.html#kafka-specific-configurations

答案 1 :(得分:1)

更新: 所以我在本地kafka实例上做了一些测试,其中一组受控消息进入kafka。我发现当属性startingOffsets设置为更早或最晚时,预期行为正常。

但是日志总是显示最早的财产,这有点误导。 auto.offset.reset =最早,即使我没有设置它。

谢谢。

答案 2 :(得分:1)

您无法根据documentation在Spark Streaming中设置auto.offset.reset。要设置为最新,您只需设置源选项startingOffsets以指定从哪里开始(最早或最晚)。结构化流媒体管理内部消耗的偏移,而不是依靠卡夫卡消费者来做。这将确保在动态订阅新主题/分区时不会遗漏任何数据。

它明确表示无法设置以下字段,而Kafka源或接收器将引发异常:

  1. group.id
  2. auto.offset.reset
  3. key.deserializer
  4. value.deserializer
  5. key.serializer
  6. value.serializer
  7. enable.auto.commit
  8. interceptor.classes

答案 3 :(得分:0)

对于结构化流,可以将startingOffsets设置为earliest,以便您每次从最早的可用偏移量开始消费。以下将解决问题

.option("startingOffsets", "earliest")

但是请注意,这仅对新创建的查询有效:

startingOffsets

查询开始的起点,"earliest"是 从最早的偏移量"latest"开始 偏移量,或一个json字符串,为每个偏移量指定一个起始偏移量 TopicPartition。在json中,可以使用-2作为偏移量来引用 最早-1到最新。注意:对于批次查询,请使用最新( 不允许隐式或通过在json中使用-1)。 用于流式传输 查询,仅在开始新查询时适用,并且 恢复将始终从查询中断的地方开始。新 在查询期间发现的分区最早将开始。


或者,您也可以选择每次更改消费者组:

.option("kafka.group.id", "newGroupID")