Spark Streaming延迟写入卡夫卡-x分钟后

时间:2019-06-06 06:57:13

标签: scala apache-spark apache-kafka spark-streaming amazon-kinesis

我们有一个Spark Streaming应用程序。 架构如下

将Kinesis激发到Kafka。

Spark应用程序正在使用qubole / kinesis-sql从Kinesis进行结构化流传输。然后汇总数据,然后将其推送到Kafka。

我们的用例需要延迟4分钟才能推送到Kafka。

加窗2分钟,水印4分钟

val windowedCountsDF = messageDS
   .withWatermark("timestamp", "4 minutes")
   .groupBy(window($"timestamp", "2 minutes", "2 minutes"), $"id", $"eventType", $"topic")

每两分钟触发一次写入Kafka的操作

val eventFilteredQuery = windowedCountsDF
  .selectExpr("topic", "id as key", "to_json(struct(*)) AS value")
  .writeStream
  .trigger(Trigger.ProcessingTime("2 minutes"))
  .format("org.apache.spark.sql.kafka010.KafkaSourceProvider")
  .option("checkpointLocation", checkPoint)
  .outputMode("update")
  .option("kafka.bootstrap.servers", kafkaBootstrapServers)
  .queryName("events_kafka_stream")
  .start()

我可以更改触发时间以匹配窗口,但是仍然有些事件会立即推送到kafka。

有什么方法可以在窗口完成后的几分钟内延迟对Kafka的写入。

谢谢

1 个答案:

答案 0 :(得分:1)

将输出模式从update更改为append(默认选项)。 output模式会将所有更新的行写入接收器,因此,是否使用水印将无关紧要。

但是,在append模式下,任何写入都需要等待,直到越过水印为止-这正是您想要的:

  

附加模式使用水印删除旧的聚合状态。但是窗口式聚合的输出会延迟withWatermark()中指定的延迟阈值,这是由于模式语义所致,行完成后(即,越过水印之后)只能将行添加到结果表一次。