使用Kafka使用Spark结构化批处理作业管理偏移量

时间:2019-02-04 22:48:33

标签: apache-spark apache-kafka apache-spark-sql spark-structured-streaming

我有一个用例,其中我正在编写批处理作业

我需要阅读一个Kafka主题并将数据记录到HDFS中。我的代码如下所示

val df: DataFrame = spark.read
  .format("kafka")
  .option("subscribe", "test-topic")
  .option("includeTimestamp", true)
  .option("kafka.bootstrap.servers", "localhost:9092")
  .option("group.id", "test-cg")
  .option("checkpointLocation", "/group/test/checkpointsDir")
  .load

df.write.
  parquet(buildPathWithCurrentBatchTime())

每次作业读取Kafka主题时,它都从最早的偏移量开始,因此同一消息被分批记录。 如何使我的作业从上一个作业实例读取的偏移量之后的偏移量开始读取消息。

我尝试设置检查点位置,组ID,但没有帮助。

我不想使用流查询。我有一个简单的用例,用于记录来自Kafka Topic的数据。我没有任何延迟要求。唯一的要求是日志中不得有任何重复项。这是低优先级。如果我使用流查询,它将一直使用执行程序,这浪费了资源。因此,我想分批处理

1 个答案:

答案 0 :(得分:1)

您正在使用的是批查询而不是流查询。 (也许会丢失位置?)只需将read替换为readStream,将write替换为writeStream即可。

编辑:正如OP所阐明的,可以使用一次触发器,我刚刚更新了代码以使用一次触发器使用结构化流。 (免责声明:我没有编译/运行代码,但所做的更改适合结构化流式处理指南文档。)

val df: DataFrame = spark.readStream
  .format("kafka")
  .option("subscribe", "test-topic")
  .option("includeTimestamp", true)
  .option("kafka.bootstrap.servers", "localhost:9092")
  .option("group.id", "test-cg")
  .option("checkpointLocation", "/group/test/checkpointsDir")
  .load

val query = df.writeStream
  .format("parquet")
  .option("path", buildPathWithCurrentBatchTime())
  .trigger(Trigger.Once())
  .start()

query.awaitTermination()