我配置了事件时处理,并且连接了一个CoFlatMapFunction
的流。我正在编写测试用例,但我发现FlatMapFunction
没有使用事件时间顺序的事件调用其方法flatMap1()
和flatMap2()
。
一些伪代码澄清
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
env.setParallelism(1)
DataStream<Integer> evenStream = env.addSource(new SourceFunction<Integer>(){
public void run(SourceContext<Integer> ctxt){
for (i=0; i < 20; i=i+2){
ctxt.collectWithTimestamp(i, i);
ctxt.emitWatermark(i);
}
}
}
)
DataStream<Integer> oddStream = env.addSource(new SourceFunction<Integer>(){
public void run(SourceContext<Integer> ctxt){
for (i=1; i < 21; i=i+2){
ctxt.collectWithTimestamp(i, i); // Using i as timestamp and watermark for this sample code, but in real code, I am using using timestamp of real event
ctxt.emitWatermark(i);
}
}
}
)
evenStream
.connect(oddStream)
.flatMap(new CoFlatMapFunction<Integer, Integer, Integer>(){
public void flatMap1(Integer evenNumber, Collector<Integer> out){
System.out.println(evenNumber);
}
public void flatMap2(Integer oddNumber, Collector<Integer> out){
System.out.println(oddNumber);
}
}
);
当我运行它时,我希望它能打印出来:
0,1,2,3,4 .... 21
这是因为我正在设置偶数和奇数的时间戳。换句话说,0具有最低时间戳,后跟1,后跟2等。
但它首先打印所有偶数,然后是奇数。
总之,我希望以我在事件中设置的时间戳的顺序调用flatMap1()和flatMap2()。但那并没有发生。
答案 0 :(得分:0)
Flink的协同功能(连接流上的功能)不保证调用其方法的顺序。只要从任一输入获得事件,就会调用这些方法(例如,flatMap1()
和flatMap2()
)。在您的示例中,偶数源生成的数据量太小,以至于奇数到达时已经处理了所有数据。
那么,事件时间处理如何协同工作?
协同功能的水印始终是两个输入的最小水印。对于CoFlatMapFunction
,这并不重要,因为您既无法读取当前水印,也无法读取记录的时间戳。但是,使用CoProcessFunction
,您可以访问两者,并且可以注册在水印达到某个时间点时调用的计时器。如果要在事件时间对输出事件进行排序,则需要缓冲传入事件(处于状态),并且当水印进展时,您可以按顺序发出所有记录,直到水印为止。