Spark结构化流-dropDuplicates与水印替代解决方案

时间:2018-12-04 22:50:45

标签: spark-structured-streaming

我正在尝试使用带有水印的dropDuplicate函数对流数据进行重复数据删除。我目前面临的问题是,给定记录需要两个时间戳记

  1. 一个是eventtimestamp-从源创建记录的时间戳。
  2. 另一个是传输时间戳-来自负责传输数据的中间过程的时间戳。

在中间阶段引入重复项,因此对于给定的记录重复项,eventtimestamp相同,但是传输时间戳不同。

对于水印,我喜欢使用transfertimestamp,因为我知道重复的间隔不能超过3分钟。但是我不能在dropDuplicate中使用它,因为它会捕获重复项,因为重复项具有不同的传输时间戳。

这里是一个例子,

Event 1:{ "EventString":"example1", "Eventtimestamp": "2018-11-29T10:00:00.00", "TransferTimestamp": "2018-11-29T10:05:00.00" }
Event 2 (duplicate): {"EventString":"example1", "Eventtimestamp": "2018-11-29T10:00:00.00", "TransferTimestamp": "2018-11-29T10:08:00.00"}

在这种情况下,副本是在原始事件发生3分钟后的传输过程中创建的

我的代码如下所示,

streamDataset.
.withWatermark("transferTimestamp", "4 minutes")
.dropDuplicates("eventstring","transferTimestamp");

上面的代码不会删除重复项,因为transferTimestamp对于事件及其重复项是唯一的。但是目前,这是唯一的方法,因为设置水印后,Spark会迫使我在dropDuplicates函数中包括水印列。

我真的很希望看到如下所示的dropDuplicate实现,这对于任何至少一次语义流都是有效的情况,在这种情况下,我不必在dropDuplicates中使用水印字段,并且仍然尊重基于水印的状态驱逐。但是目前情况并非如此

streamDataset.
.withWatermark("transferTimestamp", "4 minutes")
.dropDuplicates("eventstring");

我不能使用eventtimestamp,因为它没有顺序并且时间范围发生了很大变化(延迟事件和垃圾事件)。

如果在这种情况下有人对重复数据删除有其他解决方案或想法,请告诉我。

2 个答案:

答案 0 :(得分:0)

spark中的水印仅对有状态操作有效或受尊敬。您编写的是一个无状态操作,其中水印被忽略或用作删除重复项的组合键

答案 1 :(得分:0)

对于您的用例,您不能直接使用dropDuplicates API。您必须使用一些Spark API(例如flatmapgroupwithstate

)对它进行任意状态操作