我需要将我的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逻辑工作不正常。
我希望我的问题清楚。任何指针都会有所帮助。
答案 0 :(得分:2)
发现问题:
在处理窗口时,我没有使用显式触发器。结果,Spark尽可能快地创建了微型批处理,而不是在窗口末尾进行。
streamingQuery
.writeStream
.trigger(Trigger.ProcessingTime(windowDuration))
...
.start
这是我误解了Spark文档的结果。
注意:groupByKey使用对象的哈希码。重要的是要确保对象的哈希码是一致的。