Apache flink 带时间戳的弗林克计数器

Apache flink 带时间戳的弗林克计数器,apache-flink,flink-streaming,Apache Flink,Flink Streaming,我正在阅读Flink示例CountWithTimestamp,下面是示例中的代码片段: @Override public void processElement(Tuple2<String, String> value, Context ctx, Collector<Tuple2<String, Long>> out) throws Exception { // retrieve the current c

我正在阅读Flink示例CountWithTimestamp,下面是示例中的代码片段:

  @Override
    public void processElement(Tuple2<String, String> value, Context ctx, Collector<Tuple2<String, Long>> out)
            throws Exception {

        // retrieve the current count
        CountWithTimestamp current = state.value();
        if (current == null) {
            current = new CountWithTimestamp();
            current.key = value.f0;
        }

        // update the state's count
        current.count++;

        // set the state's timestamp to the record's assigned event time timestamp
        current.lastModified = ctx.timestamp();

        // write the state back
        state.update(current);

        // schedule the next timer 60 seconds from the current event time
        ctx.timerService().registerEventTimeTimer(current.lastModified + 60000);
    }

    @Override
    public void onTimer(long timestamp, OnTimerContext ctx, Collector<Tuple2<String, Long>> out)
            throws Exception {

        // get the state for the key that scheduled the timer
        CountWithTimestamp result = state.value();

        // check if this is an outdated timer or the latest timer
        if (timestamp == result.lastModified + 60000) {
            // emit the state on timeout
            out.collect(new Tuple2<String, Long>(result.key, result.count));
        }
    }
}
@覆盖
公共void processElement(Tuple2值、上下文ctx、收集器输出)
抛出异常{
//检索当前计数
CountWithTimestamp current=state.value();
如果(当前==null){
当前=新计数WithTimestamp();
current.key=value.f0;
}
//更新状态的计数
current.count++;
//将状态的时间戳设置为记录分配的事件时间戳
current.lastModified=ctx.timestamp();
//回信
状态更新(当前);
//从当前事件时间开始安排下一个计时器60秒
ctx.timerService().RegisterEventTimer(current.lastModified+60000);
}
@凌驾
公用void onTimer(长时间戳、OnTimerContext ctx、收集器输出)
抛出异常{
//获取调度计时器的密钥的状态
CountWithTimestamp结果=state.value();
//检查这是过期的计时器还是最新的计时器
if(timestamp==result.lastModified+60000){
//发出超时状态
collect(新的Tuple2(result.key,result.count));
}
}
}

我的问题是,如果我删除onTimer中的if station
timestamp==result.lastModified+60000
(collect stmt not moved),并在processElement的开头用另一个if station
if(ctx.timestamp替换它,程序的符号是否相同?在语义相同的情况下,一个版本是否优于另一个版本?

您认为删除计时器的实现具有相同的语义是正确的。事实上,我最近更改了培训材料中使用的示例,以实现这一点,因为我更喜欢这种方法。我认为它更可取的原因是,所有复杂的业务逻辑都在一个地方(在
processElement
中),并且无论何时调用
onTimer
,您都知道该做什么,不需要问任何问题。此外,它的性能更高,因为检查点和最终触发的计时器更少

这个例子是在删除计时器之前为文档编写的,还没有更新

您可以找到我在这些幻灯片中提到的经过修改的示例-----一旦您通过注册页面

FWIW,我最近还按照同样的思路重新编写了相应培训练习的参考解决方案: