Apache flink onTimer方法,为什么计时器状态为空?

Apache flink onTimer方法,为什么计时器状态为空?,apache-flink,flink-streaming,Apache Flink,Flink Streaming,我有这样一个简单的应用程序(内置键控进程函数) 正如您在下面的代码部分所看到的,我总是首先从状态获取timerObject,如果它不存在,我将创建一个新的,并更新状态。因此,永远不会有空/空状态 基本上,这种状态只是为了上次保存对象,例如: 如果在时间10:15看到物体,则登记时间为10:30 但是,如果在时间10:25再次看到对象,则注册时间将更新为10:40 若进程函数在时间10:40运行,这意味着15分钟内并没有对象,那个么我只是在清除我的状态 问题是记录器有时会为状态对象打印null

我有这样一个简单的应用程序(内置键控进程函数)

正如您在下面的代码部分所看到的,我总是首先从状态获取timerObject,如果它不存在,我将创建一个新的,并更新状态。因此,永远不会有空/空状态

基本上,这种状态只是为了上次保存对象,例如:

  • 如果在时间10:15看到物体,则登记时间为10:30
  • 但是,如果在时间10:25再次看到对象,则注册时间将更新为10:40
  • 若进程函数在时间10:40运行,这意味着15分钟内并没有对象,那个么我只是在清除我的状态
问题是记录器有时会为状态对象打印null。情况不应该是这样的,对吗?

公共类ProcessRule扩展了KeyedProcessFunction{
私有静态最终记录器Logger=LoggerFactory.getLogger(ProcessRule.class);
私有瞬态值状态定时器状态;
@凌驾
公共void open(配置参数)引发异常{
ValueStateDescriptor timerValueStateDescriptor=新的ValueStateDescriptor(
“timerStateForProcessRule”,
TypeInformation.of(TimerObject.class)
);
timerState=getRuntimeContext().getState(timerValueStateDescriptor);
}
@凌驾
public void processElement(LogEntity值、上下文ctx、收集器输出)引发异常{
注册表项(值,ctx);
if(条件true){
转换结果添加到收集器
}
}
私有void注册表项(LogEntity元素,Context ctx)引发异常{
TimerObject stateTimer=timerState.value();
if(stateTimer==null){
stateTimer=新的TimerObject();
长时间间隔=15*60*1000;
stateTimer.setTimeInterval(timeInterval);
}
stateTimer.setCurrentTimeinMillics(element.getTimeStamps());
timerState.update(stateTimer);
timerService().RegisterProcessingTimer(stateTimer.getNextTimer());
//getNextTimer=>currentTime+timeInterval
}
@凌驾
public void onTimer(长时间戳、OnTimerContext ctx、收集器输出)引发异常{
TimerObject stateTimer=timerState.value();
info(“在时间戳:{}处触发的计时器:{}”,时间戳,stateTimer);
timerState.clear();
}
}

这里的问题很可能是因为您正在注册多个不同的计时器,但在注册新计时器时似乎没有删除它们。因此,这基本上意味着当第一个计时器触发时,
timerState
被清除,但第二个计时器也可能再次触发,因为它可能在第一个计时器触发3秒后被注册为触发,在这种情况下,
timerState
可能已经是
null

您的意思是,我应该调用ctx.timerService().DeleteProcessingTimer(长时间);在注册新时间之前?如果是,则此deleteTimer的参数应与先前注册的计时器完全相同,或者可以等于或大于先前注册的计时器。(我假设DeleteProcessingTimer(123123)将删除“123123”之前或等于“123123”的“所有计时器”)。它应该与注册的计时器完全相同,您可以保留以前注册的计时器的时间戳,或者查看是否可以从
TimerObject
获取它。因此,在
注册表项
功能中,您可以删除上一个计时器。另一种选择是忽略它,但您需要考虑多个计时器可能会连续触发,并且状态实际上可能为null。注意:注册太多的计时器可能会影响性能和检查点大小,所以在这样做时应该考虑一下。