鞋子(一个事件(被定义为它的颜色和isLeft
(如果鞋子是左腿的,那么isLeft=true
否则false
(。
Tuple2<String, Boolean> leftBlueShoe = Tuple2.of("blue", true);
Tuple2<String, Boolean> rightBlueShoe = Tuple2.of("blue", false);
// unbounded stream of shoes is as follows
DataStream<Tuple2<String, Boolean>> streamOfShoes = ...
// somthing like - env.fromElements(leftBlueShoe, rightRedShoe, leftGreenShoe, rightBlueShoe, ...);
如何形成一双相同颜色的鞋子并期望匹配的鞋子立即发出,不匹配的鞋子等待它的一双直到窗口结束。
DataStream<Tuple5<String, Boolean, String, Boolean, String>> shoePairs = ...
// few events from shoePairs stream:
Tuple5<> shoePair = Tuple5.of("blue", true, "blue", false, "pairFound");
Tuple5<> notShoePair= Tuple5.of("red", true, "red", false, "pairNotFound"); // Even if pair not found in window we tagged and kept in stream
尝试过的方法(忽略此选项以避免混淆(:
通过将流拆分为左右流并在连接上窗口化(是否会产生成本?
翻滚窗口连接:窗口函数无法处理不匹配的对。那只鞋在窗户过去后丢失了。
CoGroupFunction:窗口不会触发最后一个事件。完整代码
低级联接:即
CoProcessFunction()
.不确定是否有帮助?
在同一个流上窗口化,
apply()
中使用TumblingProcessingTimeWindow
和自定义联接逻辑。即使所有事件都配对,也不会立即触发此窗口。
Flink 训练中的一个练习是关于查找事件对的;它的精神与你所要求的相似。请参阅乘车和票价练习,该练习使用RichCoFlatMapFunction
进行配对。
那里的解决方案假设完美配对总是可能的,因此它不能解决不匹配配对的情况。但是你可以在这里找到一个变体,更进一步。此示例使用CoProcessFunction
中的计时器来检测不匹配的对。
其他要点:
将流拆分为左右子流的成本可以忽略不计。
我认为CoGroupFunction
应该有效。如果您尝试了此操作,但它似乎不起作用,则可能是您正在使用事件时间窗口并且缺少最终水印,从而阻止窗口关闭。
更新:
查看您的代码后,我在实现中发现了一个问题。时间戳提取器在事件中使用系统时钟而不是时间戳。这将为您提供类似于(但比使用(处理时间类似的东西。我说"比处理时间更糟糕"是因为您允许事件无序,这会增加延迟,并且它会阻止窗口关闭,直到完全超出窗口终点的事件到达。这意味着永远无法触发最后一个窗口。
作为测试,尝试将时间特征切换到处理时间,删除assignTimestampsAndWatermarks
,然后查看 CoGroupFunction 是否正常工作。你也可以使用摄取时间,只要你去掉你的水印,让 Flink 处理它(处理时间水印是无关紧要的;对于摄取时间,Flink 会为你做水印,除非你覆盖它(。
如果要在应用程序中使用事件时间,请在测试中使用有限源。当有限源(例如从文件或集合中读取(到达其输入的末尾时,它们会通过作业发送非常大的水印,这将关闭任何打开的窗口。