如何在Java中使用窗口函数在结构化流中使dropDuplicates的状态到期以避免OOM?

时间:2019-01-17 07:42:24

标签: apache-spark apache-spark-sql duplicates out-of-memory spark-structured-streaming

我正在Spark结构化流2.2.1中使用dropDuplicates()方法,并且需要使用withWatermark()的有效解决方案,以减少状态。

我第一次尝试做到这一点是不正确的,因为我没有使用withWatermark()中定义的timestamp列来删除重复项,因为我实际上只想基于uuid列删除重复项在唯一的时间戳上。

然后我找到了答案https://stackoverflow.com/a/45543643,并认为我的问题已解决。但是我似乎以某种方式错误地实施了该计划,因为该州似乎仍会无限期增长并且永远不会被清理。

我遇到的情况是,在调用dropDuplicates()之后需要一个数据集,因此我向原始数据集添加了一个15分钟窗口的列,然后在该窗口上应用了watermark()并将“ window”列添加到了dropDuplicates( )。由于我需要的数据与应用dropDuplicates()之前的数据相同,因此我删除了“窗口”列,并使用相应的Encoder来获得所需的数据集。

这是我的代码:

Dataset<Context> contextDataset = ...;

contextDataset
   .withColumn("window", functions.window(contextDataset.col("timestamp"), "15 minutes"))
   .withWatermark("window", "15 minutes")
   .dropDuplicates("uuid", "window")
   .drop("window")
   .as(Context.encoder());

我的设置是:从Kafka主题最多读取350000条消息,触发时间为5分钟。当我使用时:

contextDataset
   .withWatermark("timestamp", "15 minutes")
   .dropDuplicates("uuid", "timestamp")
微批次最多需要2.5分钟。 将上述解决方案与“窗口”一起使用时,流会在一段时间后降级,并且微批处理需要2个小时才能完成许多失败的任务,而且情况越来越糟。

0 个答案:

没有答案