ProcessFunction是一个低层次的流处理操作,可以认为是能够访问到keyed state和timers的FlatMapFunction,输入流中接收到的每个事件都会调用它来处理。
对于容错性状态,ProcessFunction可以通过RuntimeContext来访问Flink的keyed state,方法与其他状态性函数访问keyed state一样。1
stream.keyBy(...).process(new MyProcessFunction())
本案例中我们将利用 timer 来判断何时 收齐 了某个 window 下所有商品的点击量数据。
1 | /** 求某个窗口中前 N 名的热门点击商品,key 为窗口时间戳,输出为 TopN 的结果字符串 */ |
- 为什么要注册windowEnd+1定时器?
- 由于 Watermark 的进度是全局的,在 processElement 方法中,每当收到一条数据( ItemViewCount ),我们就注册一个 windowEnd+1 的定时器(Flink 框架会自动忽略同一时间的重复注册,因此可以重复注册)
- windowEnd+1 的定时器被触发时,应该是到下一个窗口了,即收齐了该 windowEnd 下的所有商品窗口统计值
- ListState是做什么用的
使用了 ListState来存储收到的每条 ItemViewCount 消息,保证在发生故障时,状态数据的不丢失和一致性。 ListState 是 Flink 提供的类似 Java List 接口的 State API,它集成了框架的 checkpoint 机制,自动做到了 exactly-once 的语义保证。