Apache flink Ververica Flink培训教材中关于过期状态解的困惑
不幸的是,ververica最初的培训被更改并重定向到另一个页面,这导致我无法再次查看该示例的介绍,我确实找到了一些其他示例,但对于这个特定的示例,我没有找到它,这是我最近一直在努力的事情 对于核心部件代码段,如下所示: 第一种处理乘车流的方法Apache flink Ververica Flink培训教材中关于过期状态解的困惑,apache-flink,connect,Apache Flink,Connect,不幸的是,ververica最初的培训被更改并重定向到另一个页面,这导致我无法再次查看该示例的介绍,我确实找到了一些其他示例,但对于这个特定的示例,我没有找到它,这是我最近一直在努力的事情 对于核心部件代码段,如下所示: 第一种处理乘车流的方法 @Override public void processElement1(TaxiRide ride, Context context, Collector<Tuple2<TaxiRide, TaxiFare
@Override
public void processElement1(TaxiRide ride, Context context, Collector<Tuple2<TaxiRide, TaxiFare>> out) throws Exception {
TaxiFare fare = fareState.value();
TimerService service = context.timerService();
System.out.println("ride time service current watermark ===> " + service.currentWatermark() + "; timestamp ===>" + context.timestamp());
System.out.println("ride state ===> " + fare);
if (fare != null) {
System.out.println("fare is not null ===>" + fare.rideId);
fareState.clear();
context.timerService().deleteEventTimeTimer(fare.getEventTime());
out.collect(new Tuple2(ride, fare));
} else {
System.out.println("update ride state ===> " + ride.rideId + "===>" + context.timestamp());
rideState.update(ride);
System.out.println(rideState.value());
// as soon as the watermark arrives, we can stop waiting for the corresponding fare
context.timerService().registerEventTimeTimer(ride.getEventTime());
}
}
第二个是,因为ValueState是一个值,而不是一个包含很多值的列表,对于每次调用processElemnt2,如果ride为null,它将转到else,在调用fareState.update()之后,它将更改ValueState的值,从我的角度看,这意味着它认为ValueState的前一个值是匹配的,对吗-----最大的难题
谢谢你的回答,我非常感谢你的帮助 关于和的新教程将帮助您解答问题。但简单地说:
processElement1
和processElement2
回调的顺序。这两个输入流相互竞争,Flink运行时将根据需要处理来自一个流或另一个流的事件。在计时和/或排序很重要的情况下,您可能会发现有必要在托管Flink状态下缓冲事件,直到您的应用程序准备好处理它们为止processElement
回调的情况下),或者是创建计时器的键(在onTimer
回调的情况下)- 产生正确的结果
- 不泄漏状态
- 易懂
- 表现良好
processElement1
中发现了该代码(顺便说一下,processElement2
是相同的,只是在乘坐和票价之间角色颠倒):
public void processElement1(滑行设施、上下文、收集器输出)引发异常{
出租车票价=fareState.value();
如果(票价!=null){
fareState.clear();
context.timerService().deleteEventTimeTimer(fare.getEventTime());
外出。领取(新的Tuple2(乘车、车费));
}否则{
骑乘状态更新(骑乘);
//一旦水印到达,我们就可以停止等待相应的车费
context.timerService().RegisterEventTimer(ride.getEventTime());
}
}
这意味着
- 每当一个未完成配对的事件到达时,我们将其存储在状态并创建一个计时器
- 每当一个完成配对的事件到达时,我们清除状态并删除匹配事件(先前存储的)的计时器
public void onTimer(长时间戳、OnTimerContext ctx、收集器输出)引发异常{
if(fareState.value()!=null){
输出(不匹配的区域,fareState.value());
fareState.clear();
}
if(rideState.value()!=null){
ctx.output(unmatchDrides,rideState.value());
清除();
}
}
好的,但是我们怎么决定要等多久呢?等待ride.getEventTime()足够吗
为ride.getEventTime()
设置事件时间计时器的效果是等待,直到解决了乘坐和票价流中的任何无序情况。当水印到达ride.getEventTime(),时,所有早期的乘车和票价事件都已到达,假设水印是完美的
在这些练习中,水印实际上是完美的——不可能有延迟事件。但是在现实环境中,您应该预料到一些后期事件,并且我们应该预料我们的实现在这种情况下会正确运行。此参考解决方案将执行以下操作:
- 匹配对中的一个事件将首先到达,并创建一个计时器来安排其最终删除
- 计时器将启动,事件将被清除
- 匹配事件延迟到达,并创建另一个计时器,在本例中是针对已经过去的时间
- 下一个到达的水印触发该计时器,并且状态被清除
context.timerService().RegisterEventTimer(ride.getEventTime()+允许延迟);
尝试容纳任意延迟事件不是一个好主意,因为这样做需要无限期地为每个延迟事件保留一些状态
改用处理时间计时器怎么样?
当然,那是
@Override
public void processElement2(TaxiFare fare, Context context, Collector<Tuple2<TaxiRide, TaxiFare>> out) throws Exception {
TimerService service = context.timerService();
System.out.println("fare time service current watermark ===> " + service.currentWatermark() + "; timestamp ===>" + context.timestamp());
TaxiRide ride = rideState.value();
System.out.println("fare state ===> " + ride);
if (ride != null) {
System.out.println("ride is not null ===> " + ride.rideId);
rideState.clear();
context.timerService().deleteEventTimeTimer(ride.getEventTime());
out.collect(new Tuple2(ride, fare));
} else {
System.out.println("update fare state ===> " + fare.rideId + "===>" + context.timestamp());
fareState.update(fare);
System.out.println(fareState.value() + "===>" + fareState.value().getEventTime());
// as soon as the watermark arrives, we can stop waiting for the corresponding ride
context.timerService().registerEventTimeTimer(fare.getEventTime());
}
}
fare time service current watermark ===> -9223372036854775808; timestamp ===>1356998400000
fare time service current watermark ===> -9223372036854775808; timestamp ===>1356998400000
fare state ===> null
fare state ===> null
update fare state ===> 26===>1356998400000
update fare state ===> 58===>1356998400000
58,2013000058,2013000058,2013-01-01 00:00:00,CRD,2.0,0.0,27.0===>1356998400000
26,2013000026,2013000026,2013-01-01 00:00:00,CRD,2.0,0.0,12.5===>1356998400000
fare time service current watermark ===> -9223372036854775808; timestamp ===>1356998400000
fare state ===> null
update fare state ===> 9===>1356998400000
fare time service current watermark ===> -9223372036854775808; timestamp ===>1356998400000
fare state ===> null
update fare state ===> 47===>1356998400000
9,2013000009,2013000009,2013-01-01 00:00:00,CRD,1.0,0.0,6.0===>1356998400000
47,2013000047,2013000047,2013-01-01 00:00:00,CRD,0.9,0.0,5.9===>1356998400000
fare time service current watermark ===> -9223372036854775808; timestamp ===>1356998400000
fare state ===> null
update fare state ===> 54===>1356998400000
fare time service current watermark ===> -9223372036854775808; timestamp ===>1356998400000
54,2013000054,2013000054,2013-01-01 00:00:00,CSH,0.0,0.0,31.0===>1356998400000