与deviceid对应的Spark结构化流水印

时间:2019-08-22 04:45:00

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

传入数据是流,如下所示,由3列组成

[
 system -> deviceId,
 time -> eventTime
 value -> some metric
]
+-------+-------------------+-----+
|system |time               |value|
+-------+-------------------+-----+
|system1|2019-08-20 07:13:10|1.5  |
|system2|2019-08-20 07:11:10|1.9  |
|system3|2019-08-20 07:13:15|1.3  |
|system1|2019-08-20 07:13:20|1.8  |
|system2|2019-08-20 07:11:20|1.6  |
|system3|2019-08-20 07:13:25|1.4  |
|system1|2019-08-20 07:13:30|1.2  |
|system2|2019-08-20 07:11:30|1.1  |
|system3|2019-08-20 07:13:35|1.5  |
+-------+-------------------+-----+

每个设备以固定间隔[10秒]产生数据,

我有一个Spark结构化的流应用程序,它可以使用

计算价值的最大值

窗口持续时间= 30秒

滑动时间= 30秒

      df.withWatermark("time", "30 seconds")
      .groupBy(
        window(col("time"), "30 seconds", "30 seconds"),
        col("system")
      )
      .agg(max("value"))

问题 由于每个设备都是独立的,因此时钟也是独立的。由于各种原因,例如:[网络问题,设备的高使用率等]

,设备可能被阻塞并延迟了数据发送

现在作为单个作业处理数据,它将开始基于水印删除阻塞设备的数据,而我们正在丢失数据。

有什么办法或解决方法,以便可以将水印与deviceId绑定在一起。因此该作业会按[deviceId EventTime]维护水印,并且不会因为其他设备而丢弃它。

1 个答案:

答案 0 :(得分:0)

https://towardsdatascience.com/watermarking-in-spark-structured-streaming-9e164f373e9中,我无法自己说得更好:

  

自Spark 2.1以来,水印已引入结构化流中   API。您只需将withWatermark-Operator添加到   查询:

     

withWatermark(eventTime:String,delayThreshold:String):

     

Dataset [T]它需要两个参数,a)事件时间列(必须为   与汇总工作相同)和b)指定阈值   应该处理多长时间的数据(以事件时间为单位)。的   然后,Spark将保持聚合的状态,直到达到最大值   eventTime — delayThreshold> T,其中最大eventTime是最新的   引擎看到的事件时间,T是窗口的开始时间。   如果最新数据落入此阈值内,则查询将更新   最终(下图中的右图)。否则会得到   删除并且不会触发任何重新处理(下图左图)。

如您所见,该概念不涉及添加元数据拆分,例如设备ID。