如何在Spark结构化流媒体中为每个书面记录的微批量生成时间戳?

时间:2018-09-28 19:38:17

标签: apache-spark spark-structured-streaming

我正在从Kinesis读取数据,并通过Spark结构化流将其写入ElasticEearch。我需要存储每个微批写入到ElasticSearch索引的时间戳,作为每个记录中字段的一部分。

例如,流中的第一个微批处理包含10K条记录,这些10K条记录的时间戳应反映它们被处理(或写入ElasticSearch)的时间。然后,当处理第二个微批处理时,我们应该有一个新的时间戳,依此类推。

我尝试使用current_timestamp函数添加新列:

.withColumn("recordDate", current_timestamp())

但是看起来该函数在整个查询生命周期中仅被评估一次。结果,所有存储的记录将具有相同的时间戳,指示查询开始的时刻。因此,此时间戳似乎表示“查询开始日期时间”,而不是所需的表示“记录日期时间”的时间戳。

如果有人能够帮助解释如何实现这一目标,那将非常好。

非常感谢

1 个答案:

答案 0 :(得分:3)

您可以使用如下所示的udf进行此操作,也可以添加自己的格式,

import org.apache.spark.sql.functions.udf

 def current_time = udf(() => {
    java.time.LocalDateTime.now().toString
  })

要使用它,

val streamingDF = ???
val streamingDFWithTime .withColumn("time", current_time()))
streamingDFWithTime.writeStream
...
...

PS:我使用udf代替了内置current_timestamp,因为直接在流中使用它会导致讨论herehere

的问题

希望这会有所帮助。