我尝试使用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
。我没有看到与此特定问题相关的帖子。
我想知道我是否在这里遗漏了一些东西,如果有人之前已经看过这种行为。任何帮助/方向确实有用。谢谢。
答案 0 :(得分:3)
kafka.
前缀设置。因此,正确的选项键是kafka.auto.offset.reset
。auto.offset.reset
。相反,“设置源选项startingOffsets
以指定从哪里开始。结构化流式传输管理内部消耗的偏移,而不是依靠kafka Consumer来执行此操作。这将确保在新主题时不会遗漏任何数据/ partitions是动态订阅的。注意startingOffsets
仅在启动新的流式查询时适用,并且恢复将始终从查询中断的地方开始。“ [1] 答案 1 :(得分:1)
更新: 所以我在本地kafka实例上做了一些测试,其中一组受控消息进入kafka。我发现当属性startingOffsets设置为更早或最晚时,预期行为正常。
但是日志总是显示最早的财产,这有点误导。 auto.offset.reset =最早,即使我没有设置它。
谢谢。
答案 2 :(得分:1)
您无法根据documentation在Spark Streaming中设置auto.offset.reset。要设置为最新,您只需设置源选项startingOffsets
以指定从哪里开始(最早或最晚)。结构化流媒体管理内部消耗的偏移,而不是依靠卡夫卡消费者来做。这将确保在动态订阅新主题/分区时不会遗漏任何数据。
它明确表示无法设置以下字段,而Kafka源或接收器将引发异常:
答案 3 :(得分:0)
对于结构化流,可以将startingOffsets
设置为earliest
,以便您每次从最早的可用偏移量开始消费。以下将解决问题
.option("startingOffsets", "earliest")
但是请注意,这仅对新创建的查询有效:
查询开始的起点,
"earliest"
是 从最早的偏移量"latest"
开始 偏移量,或一个json字符串,为每个偏移量指定一个起始偏移量 TopicPartition。在json中,可以使用-2
作为偏移量来引用 最早-1
到最新。注意:对于批次查询,请使用最新( 不允许隐式或通过在json中使用-1
)。 用于流式传输 查询,仅在开始新查询时适用,并且 恢复将始终从查询中断的地方开始。新 在查询期间发现的分区最早将开始。
或者,您也可以选择每次更改消费者组:
.option("kafka.group.id", "newGroupID")