时间窗口上的Spark结构化流groupByKey不起作用

时间:2019-03-05 02:02:34

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

我需要将我的Kafka流批处理到每个10分钟的时间窗口中,然后对其进行一些批处理。

注意:下面的记录有一个时间戳记字段

   val records = spark.readStream
      .format("kafka")
      .option("kafka.bootstrap.servers", brokerPool)
      .option("subscribe", topic)
      .option("startingOffsets", kafkaOffset)
      .load()

我使用以下方式向每个记录添加一个时间窗口

.withColumn("window", window($"timing", windowDuration))

我创建了一些辅助类,例如

  case class TimingWindow(
      start: java.sql.Timestamp,
      end: java.sql.Timestamp
  )
  case class RecordWithWindow(
      record: MyRecord,
      groupingWindow: TimingWindow
  )

现在我有一个[RecordWithWindow]类型的DF

所有这些都很好。

下一步

metricsWithWindow
  .groupByKey(_.groupingWindow)
  //By grouping, I get several records per time window
  //resulting an object of the below type which I write out to HDFS

  case class WindowWithRecords(
      records: Seq[MyRecord],
      window: TimingWindow
  )

我在检查HDFS的地方,

示例

预期: 每个WindowWithRecords对象都有一个唯一的TimingWindow

WindowWithRecordsA(TimingWindowA, Seq(MyRecordA, MyRecordB, MyRecordC))

实际: 具有相同TimingWindow的多个WindowWithRecords对象

WindowWithRecordsA(TimingWindowA, Seq(MyRecordA, MyRecordB))
WindowWithRecordsB(TimingWindowA, Seq(MyRecordC))

好像groupByKey逻辑工作不正常。

我希望我的问题清楚。任何指针都会有所帮助。

1 个答案:

答案 0 :(得分:2)

发现问题:

在处理窗口时,我没有使用显式触发器。结果,Spark尽可能快地创建了微型批处理,而不是在窗口末尾进行。

streamingQuery
.writeStream
.trigger(Trigger.ProcessingTime(windowDuration))
...
.start

这是我误解了Spark文档的结果。

注意:groupByKey使用对象的哈希码。重要的是要确保对象的哈希码是一致的。